[cfe-commits] r117305 - in /cfe/trunk: lib/Sema/SemaExpr.cpp test/Sema/knr-def-call.c

Douglas Gregor dgregor at apple.com
Mon Oct 25 13:39:23 PDT 2010


Author: dgregor
Date: Mon Oct 25 15:39:23 2010
New Revision: 117305

URL: http://llvm.org/viewvc/llvm-project?rev=117305&view=rev
Log:
When we're calling a function that we know based on its K&R-style
function definition, we should still use a prototype to type-check and
convert the function arguments, if such a prototype exists. Fixes
PR8314.

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/Sema/knr-def-call.c

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=117305&r1=117304&r2=117305&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Oct 25 15:39:23 2010
@@ -3836,24 +3836,51 @@
       // on our knowledge of the function definition.
       const FunctionDecl *Def = 0;
       if (FDecl->hasBody(Def) && NumArgs != Def->param_size()) {
-        const FunctionProtoType *Proto =
-            Def->getType()->getAs<FunctionProtoType>();
-        if (!Proto || !(Proto->isVariadic() && NumArgs >= Def->param_size())) {
+        const FunctionProtoType *Proto 
+          = Def->getType()->getAs<FunctionProtoType>();
+        if (!Proto || !(Proto->isVariadic() && NumArgs >= Def->param_size()))
           Diag(RParenLoc, diag::warn_call_wrong_number_of_arguments)
             << (NumArgs > Def->param_size()) << FDecl << Fn->getSourceRange();
-        }
       }
+      
+      // If the function we're calling isn't a function prototype, but we have
+      // a function prototype from a prior declaratiom, use that prototype.
+      if (!FDecl->hasPrototype())
+        Proto = FDecl->getType()->getAs<FunctionProtoType>();
     }
 
     // Promote the arguments (C99 6.5.2.2p6).
     for (unsigned i = 0; i != NumArgs; i++) {
       Expr *Arg = Args[i];
-      DefaultArgumentPromotion(Arg);
-      if (RequireCompleteType(Arg->getSourceRange().getBegin(),
-                              Arg->getType(),
-                              PDiag(diag::err_call_incomplete_argument)
-                                << Arg->getSourceRange()))
-        return ExprError();
+
+      if (Proto && i < Proto->getNumArgs()) {
+        if (RequireCompleteType(Arg->getSourceRange().getBegin(),
+                                Arg->getType(),
+                                PDiag(diag::err_call_incomplete_argument)
+                                  << Arg->getSourceRange()))
+          return ExprError();
+
+        InitializedEntity Entity
+          = InitializedEntity::InitializeParameter(Context, 
+                                                   Proto->getArgType(i));
+        ExprResult ArgE = PerformCopyInitialization(Entity,
+                                                    SourceLocation(),
+                                                    Owned(Arg));
+        if (ArgE.isInvalid())
+          return true;
+        
+        Arg = ArgE.takeAs<Expr>();
+
+      } else {
+        DefaultArgumentPromotion(Arg);
+
+        if (RequireCompleteType(Arg->getSourceRange().getBegin(),
+                                Arg->getType(),
+                                PDiag(diag::err_call_incomplete_argument)
+                                  << Arg->getSourceRange()))
+          return ExprError();
+      }
+      
       TheCall->setArg(i, Arg);
     }
   }

Modified: cfe/trunk/test/Sema/knr-def-call.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/knr-def-call.c?rev=117305&r1=117304&r2=117305&view=diff
==============================================================================
--- cfe/trunk/test/Sema/knr-def-call.c (original)
+++ cfe/trunk/test/Sema/knr-def-call.c Mon Oct 25 15:39:23 2010
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -Wconversion -fsyntax-only -verify %s
 
 // C DR #316, PR 3626.
 void f0(a, b, c, d) int a,b,c,d; {}
@@ -27,3 +27,14 @@
 {
   return 0;
 }
+
+// PR8314
+void proto(int);
+void proto(x) 
+     int x;
+{
+}
+
+void use_proto() {
+  proto(42.0); // expected-warning{{implicit conversion turns floating-point number into integer: 'double' to 'int'}}
+}





More information about the cfe-commits mailing list