improve error recovery handling broken 'then' or 'else' stmts in

if statements.  This implements Sema/if-empty-body.c:f3, silencing
a bogus secondary warning.  It also improve the location info for
the nullstmts created for recovery purposes.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43440 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-10-29 05:08:52 +00:00
Родитель 85f9bceab1
Коммит b96728d90a
2 изменённых файлов: 34 добавлений и 10 удалений

Просмотреть файл

@ -512,19 +512,18 @@ Parser::StmtResult Parser::ParseIfStatement() {
bool NeedsInnerScope = getLang().C99 && Tok.isNot(tok::l_brace); bool NeedsInnerScope = getLang().C99 && Tok.isNot(tok::l_brace);
if (NeedsInnerScope) EnterScope(Scope::DeclScope); if (NeedsInnerScope) EnterScope(Scope::DeclScope);
// Read the if condition. // Read the 'then' stmt.
StmtResult CondStmt = ParseStatement(); SourceLocation ThenStmtLoc = Tok.getLocation();
StmtResult ThenStmt = ParseStatement();
// Broken substmt shouldn't prevent the label from being added to the AST.
if (CondStmt.isInvalid)
CondStmt = Actions.ActOnNullStmt(Tok.getLocation());
// Pop the 'if' scope if needed. // Pop the 'if' scope if needed.
if (NeedsInnerScope) ExitScope(); if (NeedsInnerScope) ExitScope();
// If it has an else, parse it. // If it has an else, parse it.
SourceLocation ElseLoc; SourceLocation ElseLoc;
SourceLocation ElseStmtLoc;
StmtResult ElseStmt(false); StmtResult ElseStmt(false);
if (Tok.is(tok::kw_else)) { if (Tok.is(tok::kw_else)) {
ElseLoc = ConsumeToken(); ElseLoc = ConsumeToken();
@ -535,19 +534,37 @@ Parser::StmtResult Parser::ParseIfStatement() {
NeedsInnerScope = getLang().C99 && Tok.isNot(tok::l_brace); NeedsInnerScope = getLang().C99 && Tok.isNot(tok::l_brace);
if (NeedsInnerScope) EnterScope(Scope::DeclScope); if (NeedsInnerScope) EnterScope(Scope::DeclScope);
ElseStmtLoc = Tok.getLocation();
ElseStmt = ParseStatement(); ElseStmt = ParseStatement();
// Pop the 'else' scope if needed. // Pop the 'else' scope if needed.
if (NeedsInnerScope) ExitScope(); if (NeedsInnerScope) ExitScope();
if (ElseStmt.isInvalid)
ElseStmt = Actions.ActOnNullStmt(ElseLoc);
} }
if (getLang().C99) if (getLang().C99)
ExitScope(); ExitScope();
return Actions.ActOnIfStmt(IfLoc, CondExp.Val, CondStmt.Val, // If the then or else stmt is invalid and the other is valid (and present),
// make turn the invalid one into a null stmt to avoid dropping the other
// part. If both are invalid, return error.
if ((ThenStmt.isInvalid && ElseStmt.isInvalid) ||
(ThenStmt.isInvalid && ElseStmt.Val == 0) ||
(ThenStmt.Val == 0 && ElseStmt.isInvalid)) {
// Both invalid, or one is invalid and other is non-present: delete cond and
// return error.
Actions.DeleteExpr(CondExp.Val);
return true;
}
// Now if either are invalid, replace with a ';'.
if (ThenStmt.isInvalid)
ThenStmt = Actions.ActOnNullStmt(ThenStmtLoc);
if (ElseStmt.isInvalid)
ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
return Actions.ActOnIfStmt(IfLoc, CondExp.Val, ThenStmt.Val,
ElseLoc, ElseStmt.Val); ElseLoc, ElseStmt.Val);
} }

Просмотреть файл

@ -7,3 +7,10 @@ void f1(int a) {
void f2(int a) { void f2(int a) {
if (a) {} if (a) {}
} }
void f3() {
if (1)
xx; // expected-error {{use of undeclared identifier}}
return; // no empty body warning.
}