diff options
author | Chris Lattner <sabre@nondot.org> | 2010-07-11 22:42:07 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-07-11 22:42:07 +0000 |
commit | 004659a56916f2f81ede507c12516c146d6c0df3 (patch) | |
tree | ac27fa629639189ebaf1d692618b164f210a8cf6 /lib/Parse/ParseDecl.cpp | |
parent | c82daefa3062721e98947e08193cd81b4e9df915 (diff) |
Fix PR7617 by not entering ParseFunctionDefinition when
a function prototype is followed by a declarator if we
aren't parsing a K&R style identifier list.
Also, avoid skipping randomly after a declaration if a
semicolon is missing. Before we'd get:
t.c:3:1: error: expected function body after function declarator
void bar();
^
Now we get:
t.c:1:11: error: invalid token after top level declarator
void foo()
^
;
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108105 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 0334209f50..62ef3ec017 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -402,7 +402,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, // start of a function definition in GCC-extended K&R C. !isDeclarationAfterDeclarator()) { - if (isStartOfFunctionDefinition()) { + if (isStartOfFunctionDefinition(D)) { if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { Diag(Tok, diag::err_function_declared_typedef); @@ -412,6 +412,14 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, DeclPtrTy TheDecl = ParseFunctionDefinition(D); return Actions.ConvertDeclToDeclGroup(TheDecl); + } + + if (isDeclarationSpecifier()) { + // If there is an invalid declaration specifier right after the function + // prototype, then we must be in a missing semicolon case where this isn't + // actually a body. Just fall through into the code that handles it as a + // prototype, and let the top-level code handle the erroneous declspec + // where it would otherwise expect a comma or semicolon. } else { Diag(Tok, diag::err_expected_fn_body); SkipUntil(tok::semi); @@ -463,9 +471,14 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, Context == Declarator::FileContext ? diag::err_invalid_token_after_toplevel_declarator : diag::err_expected_semi_declaration)) { - SkipUntil(tok::r_brace, true, true); - if (Tok.is(tok::semi)) - ConsumeToken(); + // Okay, there was no semicolon and one was expected. If we see a + // declaration specifier, just assume it was missing and continue parsing. + // Otherwise things are very confused and we skip to recover. + if (!isDeclarationSpecifier()) { + SkipUntil(tok::r_brace, true, true); + if (Tok.is(tok::semi)) + ConsumeToken(); + } } return Actions.FinalizeDeclaratorGroup(getCurScope(), DS, |