From: Steve Naroff Date: Thu, 14 Feb 2008 02:58:32 +0000 (+0000) Subject: A much better fix for http://llvm.org/bugs/show_bug.cgi?id=1987. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e39bfd0c52975dfb038413aa55147df2fc709ce2;p=clang A much better fix for http://llvm.org/bugs/show_bug.cgi?id=1987. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47103 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Parse/Parser.cpp b/Parse/Parser.cpp index 860a44f9e9..703144b3c4 100644 --- a/Parse/Parser.cpp +++ b/Parse/Parser.cpp @@ -367,9 +367,6 @@ Parser::DeclTy *Parser::ParseDeclarationOrFunctionDefinition() { // Parse the common declaration-specifiers piece. DeclSpec DS; ParseDeclarationSpecifiers(DS); - // If the decl specs are invalid, there is no need to continue. - if (DS.isInvalid()) - return 0; // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };" // declaration-specifiers init-declarator-list[opt] ';' @@ -422,6 +419,20 @@ Parser::DeclTy *Parser::ParseDeclarationOrFunctionDefinition() { } else if (DeclaratorInfo.isFunctionDeclarator() && (Tok.is(tok::l_brace) || // int X() {} isDeclarationSpecifier())) { // int X(f) int f; {} + if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { + Diag(Tok, diag::err_function_declared_typedef); + + if (Tok.is(tok::l_brace)) { + // This recovery skips the entire function body. It would be nice + // to simply call ParseFunctionDefintion() below, however Sema + // assumes the declarator represents a function, not a typedef. + ConsumeBrace(); + SkipUntil(tok::r_brace, true); + } else { + SkipUntil(tok::semi); + } + return 0; + } return ParseFunctionDefinition(DeclaratorInfo); } else { if (DeclaratorInfo.isFunctionDeclarator()) diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 7d0e684ce7..1c97120a72 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -352,6 +352,8 @@ DIAG(err_expected_semi_decl_list, ERROR, "expected ';' at end of declaration list") DIAG(ext_expected_semi_decl_list, EXTENSION, "expected ';' at end of declaration list") +DIAG(err_function_declared_typedef, ERROR, + "function definition declared 'typedef'") DIAG(err_expected_fn_body, ERROR, "expected function body after function declarator") DIAG(err_expected_after_declarator, ERROR, diff --git a/test/Sema/declspec.c b/test/Sema/declspec.c index fd57540681..e262b343cb 100644 --- a/test/Sema/declspec.c +++ b/test/Sema/declspec.c @@ -5,8 +5,12 @@ T foo(int n, int m) { } // expected-error {{cannot return array or function}} void foof(const char *, ...) __attribute__((__format__(__printf__, 1, 2))), barf (void); +int typedef validTypeDecl() { } // expected-error {{function definition declared 'typedef'}} + struct _zend_module_entry { } typedef struct _zend_function_entry { } // expected-error {{cannot combine with previous 'struct' declaration specifier}} -static void buggy(int *x) { // expected-error {{cannot combine with previous 'typedef' declaration specifier}} \ - // expected-error {{cannot combine with previous 'struct' declaration specifier}} - // expected-error {{expected '}'}} +static void buggy(int *x) { } // expected-error {{function definition declared 'typedef'}} \ + // expected-error {{cannot combine with previous 'typedef' declaration specifier}} \ + // expected-error {{cannot combine with previous 'struct' declaration specifier}} + +