aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-07-11 22:42:07 +0000
committerChris Lattner <sabre@nondot.org>2010-07-11 22:42:07 +0000
commit004659a56916f2f81ede507c12516c146d6c0df3 (patch)
treeac27fa629639189ebaf1d692618b164f210a8cf6 /lib/Parse/ParseDecl.cpp
parentc82daefa3062721e98947e08193cd81b4e9df915 (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.cpp21
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,