aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Parse/ParseDecl.cpp19
-rw-r--r--include/clang/Basic/DiagnosticKinds.def10
-rw-r--r--test/Parser/declarators.c4
-rw-r--r--test/Sema/c89.c3
-rw-r--r--test/Sema/function.c10
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}}