diff options
-rw-r--r-- | Parse/ParseDecl.cpp | 19 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticKinds.def | 10 | ||||
-rw-r--r-- | test/Parser/declarators.c | 4 | ||||
-rw-r--r-- | test/Sema/c89.c | 3 | ||||
-rw-r--r-- | test/Sema/function.c | 10 |
5 files changed, 28 insertions, 18 deletions
diff --git a/Parse/ParseDecl.cpp b/Parse/ParseDecl.cpp index 368887298e..d6b92119c7 100644 --- a/Parse/ParseDecl.cpp +++ b/Parse/ParseDecl.cpp @@ -1362,6 +1362,8 @@ void Parser::ParseParenDeclarator(Declarator &D) { break; } + SourceLocation DSStart = Tok.getLocation(); + // Parse the declaration-specifiers. DeclSpec DS; ParseDeclarationSpecifiers(DS); @@ -1406,16 +1408,19 @@ void Parser::ParseParenDeclarator(Declarator &D) { // If no parameter was specified, verify that *something* was specified, // otherwise we have a missing type and identifier. - if (!DS.hasTypeSpecifier()) { + if (DS.getParsedSpecifiers() == DeclSpec::PQ_None && + ParmDecl.getIdentifier() == 0 && ParmDecl.getNumTypeObjects() == 0) { + Diag(DSStart, diag::err_missing_param); + } else if (!DS.hasTypeSpecifier() && + (getLang().C99 || getLang().CPlusPlus)) { + // Otherwise, if something was specified but a type specifier wasn't, + // (e.g. "x" or "restrict x" or "restrict"), this is a use of implicit + // int. This is valid in C90, but not in C99 or C++. if (ParmII) Diag(ParmDecl.getIdentifierLoc(), - diag::err_param_requires_type_specifier, ParmII->getName()); + diag::ext_param_requires_type_specifier, ParmII->getName()); else - Diag(Tok.getLocation(), diag::err_anon_param_requires_type_specifier); - - // Default the parameter to 'int'. - const char *PrevSpec = 0; - DS.SetTypeSpecType(DeclSpec::TST_int, Tok.getLocation(), PrevSpec); + Diag(DSStart, diag::ext_anon_param_requires_type_specifier); } ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 11d21775ed..7d0e684ce7 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -540,10 +540,12 @@ DIAG(ext_vla, EXTENSION, "variable length arrays are a C99 feature, accepted as an extension") DIAG(err_invalid_storage_class_in_func_decl, ERROR, "invalid storage class specifier in function declarator") -DIAG(err_anon_param_requires_type_specifier, ERROR, - "type specifier required for unnamed parameter") -DIAG(err_param_requires_type_specifier, ERROR, - "type specifier required for parameter '%0'") +DIAG(ext_anon_param_requires_type_specifier, EXTENSION, + "type specifier required for unnamed parameter, defaults to int") +DIAG(ext_param_requires_type_specifier, EXTENSION, + "type specifier required for parameter '%0', defaults to int") +DIAG(err_missing_param, ERROR, + "expected parameter declarator") DIAG(err_invalid_reference_qualifier_application, ERROR, "'%0' qualifier may not be applied to a reference") diff --git a/test/Parser/declarators.c b/test/Parser/declarators.c index e00035c8e0..aaea35c2cb 100644 --- a/test/Parser/declarators.c +++ b/test/Parser/declarators.c @@ -1,4 +1,4 @@ -// RUN: clang %s -fsyntax-only -verify +// RUN: clang %s -fsyntax-only -verify -pedantic extern int a1[]; @@ -6,7 +6,7 @@ void f0(); void f1(int [*]); void f2(int [const *]); void f3(int [volatile const*]); -int f4(*XX)(void); /* expected-error {{cannot return}} expected-error {{type specifier required}} */ +int f4(*XX)(void); /* expected-error {{cannot return}} expected-warning {{type specifier required}} */ char ((((*X)))); diff --git a/test/Sema/c89.c b/test/Sema/c89.c index 7f26e99dfa..e7568bcb1b 100644 --- a/test/Sema/c89.c +++ b/test/Sema/c89.c @@ -27,3 +27,6 @@ void test3(int i) { int test4 = 0LL; /* expected-warning {{long long}} */ +/* PR1999 */ +void test5(register); + diff --git a/test/Sema/function.c b/test/Sema/function.c index 7e593d400c..a75814ee45 100644 --- a/test/Sema/function.c +++ b/test/Sema/function.c @@ -1,4 +1,4 @@ -// RUN: clang %s -fsyntax-only -verify +// RUN: clang %s -fsyntax-only -verify -pedantic // PR1892 void f(double a[restrict][5]); // should promote to restrict ptr. void f(double (* restrict a)[5]); @@ -16,10 +16,10 @@ void g(int (*compar)()) { // PR1965 int t5(b); // expected-error {{parameter list without types}} -int t6(int x, g); // expected-error {{type specifier required for parameter 'g'}} +int t6(int x, g); // expected-warning {{type specifier required for parameter 'g'}} -int t7(, ); // expected-error {{type specifier required}} expected-error {{type specifier required}} -int t8(, int a); // expected-error {{type specifier required}} -int t9(int a, ); // expected-error {{type specifier required}} +int t7(, ); // expected-error {{expected parameter declarator}} expected-error {{expected parameter declarator}} +int t8(, int a); // expected-error {{expected parameter declarator}} +int t9(int a, ); // expected-error {{expected parameter declarator}} |