From f631997cb5473abb1b6115deeb1a83be4758e01f Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Thu, 14 Feb 2008 02:58:32 +0000 Subject: [PATCH] A much better fix for http://llvm.org/bugs/show_bug.cgi?id=1987. llvm-svn: 47103 --- clang/Parse/Parser.cpp | 17 ++++++++++++++--- clang/include/clang/Basic/DiagnosticKinds.def | 2 ++ clang/test/Sema/declspec.c | 10 +++++++--- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/clang/Parse/Parser.cpp b/clang/Parse/Parser.cpp index 860a44f9e94d..703144b3c443 100644 --- a/clang/Parse/Parser.cpp +++ b/clang/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/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 7d0e684ce7d9..1c97120a72ec 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/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/clang/test/Sema/declspec.c b/clang/test/Sema/declspec.c index fd5754068128..e262b343cbb9 100644 --- a/clang/test/Sema/declspec.c +++ b/clang/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}} + + -- GitLab