]> granicus.if.org Git - clang/commitdiff
Fix PR1999, by emitting a hard error only if an argument declarator is completely
authorChris Lattner <sabre@nondot.org>
Sun, 10 Feb 2008 23:08:00 +0000 (23:08 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 10 Feb 2008 23:08:00 +0000 (23:08 +0000)
missing.  Otherwise, it is an implicit int case, which is valid in c90 and invalid
elsewhere, but accepted as an extension.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46938 91177308-0d34-0410-b5e6-96231b3b80d8

Parse/ParseDecl.cpp
include/clang/Basic/DiagnosticKinds.def
test/Parser/declarators.c
test/Sema/c89.c
test/Sema/function.c

index 368887298e9a4c230cc57d854e0460d59ef58cde..d6b92119c7c9743df978e0d45d9d1a6fe15bb402 100644 (file)
@@ -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, 
index 11d21775ed3685e4ec64730bc9809d63c1e8d158..7d0e684ce7d9e67663c3e5ff3ebddca240a76dfb 100644 (file)
@@ -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")
index e00035c8e0fca1241bfa552d46d8e7cee8faa82d..aaea35c2cbc144d7f73ca92486f551c8a6e0d6de 100644 (file)
@@ -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))));
 
index 7f26e99dfa8ad956b79659c6d304690b127ab0c7..e7568bcb1b7f0816e2ffa291be5ea447db61e4b3 100644 (file)
@@ -27,3 +27,6 @@ void test3(int i) {
 
 int test4 = 0LL;               /* expected-warning {{long long}} */
 
+/* PR1999 */
+void test5(register);
+
index 7e593d400c905ebaa9774cdf372db1c9e6b84b85..a75814ee45e31b9176f9bb161b273ad77a013566 100644 (file)
@@ -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}}