]> granicus.if.org Git - clang/commitdiff
A much better fix for http://llvm.org/bugs/show_bug.cgi?id=1987.
authorSteve Naroff <snaroff@apple.com>
Thu, 14 Feb 2008 02:58:32 +0000 (02:58 +0000)
committerSteve Naroff <snaroff@apple.com>
Thu, 14 Feb 2008 02:58:32 +0000 (02:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47103 91177308-0d34-0410-b5e6-96231b3b80d8

Parse/Parser.cpp
include/clang/Basic/DiagnosticKinds.def
test/Sema/declspec.c

index 860a44f9e94d76a02fafbfb8a2215bda6bd2cee0..703144b3c443b796c354ea57a93c838b0535e5fb 100644 (file)
@@ -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())
index 7d0e684ce7d9e67663c3e5ff3ebddca240a76dfb..1c97120a72ecb9aa51f0a8b74eafa48bfd6a2feb 100644 (file)
@@ -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,
index fd57540681281b1188e687e515e274c9126deff5..e262b343cbb9856f45349005b3e256c8320bdbfc 100644 (file)
@@ -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}}
+
+