aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2008-02-14 02:58:32 +0000
committerSteve Naroff <snaroff@apple.com>2008-02-14 02:58:32 +0000
commite39bfd0c52975dfb038413aa55147df2fc709ce2 (patch)
tree503a331acdcab13d192766601bc3a7c90fe96fe4
parentdaeb9a7376830d637e02b5bc51faf4750a7bce70 (diff)
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
-rw-r--r--Parse/Parser.cpp17
-rw-r--r--include/clang/Basic/DiagnosticKinds.def2
-rw-r--r--test/Sema/declspec.c10
3 files changed, 23 insertions, 6 deletions
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}}
+
+