break;
}
+ SourceLocation DSStart = Tok.getLocation();
+
// Parse the declaration-specifiers.
DeclSpec DS;
ParseDeclarationSpecifiers(DS);
// 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,
"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")
-// RUN: clang %s -fsyntax-only -verify
+// RUN: clang %s -fsyntax-only -verify -pedantic
extern int a1[];
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))));
int test4 = 0LL; /* expected-warning {{long long}} */
+/* PR1999 */
+void test5(register);
+
-// 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]);
// 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}}