Fix a couple of suboptimalities in error recovery.

1. In the top level of ParseStatementOrDeclaration, don't eat a } if we
   just parsed a statement if it list there.  Also, don't even bother
   emitting an error about a missing semicolon if the statement had a 
   bug (an rbrace is fine).
2. In do/while parsing, don't require a 'while' to be present if the do
   body didn't parse.

This allows us to generate a clean diagnostic for this code:

t.c:1:22: error: expected expression
void foo (void) { do . while (0); }
                     ^

Thanks to Neil for pointing this out.

llvm-svn: 59256
This commit is contained in:
Chris Lattner 2008-11-13 18:52:53 +00:00
parent f3e388d1bf
commit 0046de17e5
2 changed files with 18 additions and 8 deletions

View File

@ -170,9 +170,10 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
// If we reached this code, the statement must end in a semicolon.
if (Tok.is(tok::semi)) {
ConsumeToken();
} else {
} else if (!Res.isInvalid) {
Diag(Tok, diag::err_expected_semi_after, SemiError);
SkipUntil(tok::semi);
// Skip until we see a } or ;, but don't eat it.
SkipUntil(tok::r_brace, true, true);
}
return Res;
}
@ -717,8 +718,8 @@ Parser::StmtResult Parser::ParseDoStatement() {
// The substatement in an iteration-statement implicitly defines a local scope
// which is entered and exited each time through the loop.
//
bool NeedsInnerScope = (getLang().C99 || getLang().CPlusPlus) &&
Tok.isNot(tok::l_brace);
bool NeedsInnerScope =
(getLang().C99 || getLang().CPlusPlus) && Tok.isNot(tok::l_brace);
if (NeedsInnerScope) EnterScope(Scope::DeclScope);
// Read the body statement.
@ -729,9 +730,11 @@ Parser::StmtResult Parser::ParseDoStatement() {
if (Tok.isNot(tok::kw_while)) {
ExitScope();
Diag(Tok, diag::err_expected_while);
Diag(DoLoc, diag::err_matching, "do");
SkipUntil(tok::semi);
if (!Body.isInvalid) {
Diag(Tok, diag::err_expected_while);
Diag(DoLoc, diag::err_matching, "do");
SkipUntil(tok::semi, false, true);
}
return true;
}
SourceLocation WhileLoc = ConsumeToken();
@ -739,7 +742,7 @@ Parser::StmtResult Parser::ParseDoStatement() {
if (Tok.isNot(tok::l_paren)) {
ExitScope();
Diag(Tok, diag::err_expected_lparen_after, "do/while");
SkipUntil(tok::semi);
SkipUntil(tok::semi, false, true);
return true;
}

View File

@ -47,3 +47,10 @@ void test5() {
if (0); // expected-warning {{if statement has empty body}}
}
void test6(void) {
do
. // expected-error {{expected expression}}
while (0);
}