[cfe-commits] r39239 - in /cfe/cfe/trunk: AST/SemaType.cpp Parse/ParseDecl.cpp Sema/SemaType.cpp include/clang/Basic/DiagnosticKinds.def

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:41:45 PDT 2007


Author: sabre
Date: Wed Jul 11 11:41:44 2007
New Revision: 39239

URL: http://llvm.org/viewvc/llvm-project?rev=39239&view=rev
Log:
Diagnose errors like:

void bar(int X, int X);

void blah(X, Y, X) int X, Y; {}

Modified:
    cfe/cfe/trunk/AST/SemaType.cpp
    cfe/cfe/trunk/Parse/ParseDecl.cpp
    cfe/cfe/trunk/Sema/SemaType.cpp
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def

Modified: cfe/cfe/trunk/AST/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaType.cpp?rev=39239&r1=39238&r2=39239&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaType.cpp (original)
+++ cfe/cfe/trunk/AST/SemaType.cpp Wed Jul 11 11:41:44 2007
@@ -147,17 +147,17 @@
           // function with no other parameters (C99 6.7.5.3p10).  We record
           // int(void) as a FunctionTypeProto with an empty argument list.
           if (ArgTy->isVoidType()) {
-            // If this is something like 'float(int, void)', reject it.
+            // If this is something like 'float(int, void)', reject it.  'void'
+            // is an incomplete type (C99 6.2.5p19) and function decls cannot
+            // have arguments of incomplete type.
             if (FTI.NumArgs != 1 || FTI.isVariadic) {
               Diag(DeclType.Loc, diag::err_void_only_param);
               return TypeRef();
             }
-            // Reject 'int(void abc)'.
-            if (FTI.ArgInfo[i].Ident) {
+            // Reject, but continue to parse 'int(void abc)'.
+            if (FTI.ArgInfo[i].Ident)
               Diag(FTI.ArgInfo[i].IdentLoc,
                    diag::err_void_param_with_identifier);
-              return TypeRef();
-            }
             
             // Reject, but continue to parse 'float(const void)'.
             if (ArgTy.getQualifiers())

Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=39239&r1=39238&r2=39239&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:41:44 2007
@@ -951,9 +951,24 @@
         break;
       }
       
+      IdentifierInfo *ParmII = Tok.getIdentifierInfo();
+      
+      // Verify that the argument identifier has not already been mentioned.
+      // Note that the implementation of this check is N^2 in # arguments.  For
+      // reasonable number of arguments though (e.g. < 32) this is faster than
+      // building a set.
+      // FIXME: we need a SmallSet<const IdentifierInfo*, 16>.
+      for (unsigned i = 0, e = ParamInfo.size(); i != e; ++i)
+        if (ParamInfo[i].Ident == ParmII) {
+          Diag(Tok.getLocation(), diag::err_param_redefinition,
+               ParmII->getName());
+          ParmII = 0;
+          break;
+        }
+          
       // Remember this identifier in ParamInfo.
-      ParamInfo.push_back(DeclaratorChunk::ParamInfo(Tok.getIdentifierInfo(),
-                                                     Tok.getLocation(), 0));
+      ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, Tok.getLocation(),
+                                                     0));
       
       // Eat the identifier.
       ConsumeToken();
@@ -1026,7 +1041,24 @@
         Actions.ParseParamDeclaratorType(CurScope, ParmDecl);
         
       // Remember this parsed parameter in ParamInfo.
-      ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmDecl.getIdentifier(),
+      IdentifierInfo *ParmII = ParmDecl.getIdentifier();
+      
+      // Verify that the argument identifier has not already been mentioned.
+      // Note that the implementation of this check is N^2 in # arguments.  For
+      // reasonable number of arguments though (e.g. < 32) this is faster than
+      // building a set.
+      // FIXME: we need a SmallSet<const IdentifierInfo*, 16>.
+      if (ParmII) {
+        for (unsigned i = 0, e = ParamInfo.size(); i != e; ++i)
+          if (ParamInfo[i].Ident == ParmII) {
+            Diag(ParmDecl.getIdentifierLoc(), diag::err_param_redefinition,
+                 ParmII->getName());
+            ParmII = 0;
+            break;
+          }
+      }
+        
+      ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
                                                     ParmDecl.getIdentifierLoc(),
                                                      ParamTy.Val));
       

Modified: cfe/cfe/trunk/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaType.cpp?rev=39239&r1=39238&r2=39239&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaType.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaType.cpp Wed Jul 11 11:41:44 2007
@@ -147,17 +147,17 @@
           // function with no other parameters (C99 6.7.5.3p10).  We record
           // int(void) as a FunctionTypeProto with an empty argument list.
           if (ArgTy->isVoidType()) {
-            // If this is something like 'float(int, void)', reject it.
+            // If this is something like 'float(int, void)', reject it.  'void'
+            // is an incomplete type (C99 6.2.5p19) and function decls cannot
+            // have arguments of incomplete type.
             if (FTI.NumArgs != 1 || FTI.isVariadic) {
               Diag(DeclType.Loc, diag::err_void_only_param);
               return TypeRef();
             }
-            // Reject 'int(void abc)'.
-            if (FTI.ArgInfo[i].Ident) {
+            // Reject, but continue to parse 'int(void abc)'.
+            if (FTI.ArgInfo[i].Ident)
               Diag(FTI.ArgInfo[i].IdentLoc,
                    diag::err_void_param_with_identifier);
-              return TypeRef();
-            }
             
             // Reject, but continue to parse 'float(const void)'.
             if (ArgTy.getQualifiers())

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39239&r1=39238&r2=39239&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:41:44 2007
@@ -393,12 +393,15 @@
 DIAG(err_invalid_storage_class_in_func_decl, ERROR,
      "invalid storage class specifier in function declarator")
 
+// Function Parameter Semantic Analysis.
 DIAG(err_void_param_with_identifier, ERROR,
      "void argument may not have a name")
 DIAG(err_void_only_param, ERROR,
      "'void' must be the first and only parameter if specified")
 DIAG(err_void_param_qualified, ERROR,
      "'void' as parameter must not have type qualifiers")
+DIAG(err_param_redefinition, ERROR,
+     "redefinition of parameter '%s'")
 
 DIAG(err_unexpected_typedef, ERROR,
      "unexpected type name '%s': expected expression")





More information about the cfe-commits mailing list