]> granicus.if.org Git - clang/commitdiff
fix rdar://7985267 - Don't emit an error about a non-pod argument
authorChris Lattner <sabre@nondot.org>
Sun, 16 May 2010 04:01:30 +0000 (04:01 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 16 May 2010 04:01:30 +0000 (04:01 +0000)
passed to va_start, it doesn't actually pass it.

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

lib/Sema/Sema.h
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprObjC.cpp
lib/Sema/SemaOverload.cpp
test/SemaCXX/vararg-non-pod.cpp

index 3e143bb3b00c16d44e8abc8e8c099fd4481382f6..a7d242c559b54fc80e1f85f891bd5cd4f9b119f6 100644 (file)
@@ -4093,7 +4093,8 @@ public:
 
   // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
   // will warn if the resulting type is not a POD type.
-  bool DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT);
+  bool DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT,
+                                        FunctionDecl *FDecl);
 
   // UsualArithmeticConversions - performs the UsualUnaryConversions on it's
   // operands and then handles various conversions that are common to binary
index 60c716353a90ef22524d6f492db6e563a07b104f..5a24a2c4c0a3721abcb6b81902cc27c0e65d41a4 100644 (file)
@@ -279,10 +279,9 @@ void Sema::DefaultArgumentPromotion(Expr *&Expr) {
   assert(!Ty.isNull() && "DefaultArgumentPromotion - missing type");
 
   // If this is a 'float' (CVR qualified or typedef) promote to double.
-  if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
-    if (BT->getKind() == BuiltinType::Float)
-      return ImpCastExprToType(Expr, Context.DoubleTy,
-                               CastExpr::CK_FloatingCast);
+  if (Ty->isSpecificBuiltinType(BuiltinType::Float))
+    return ImpCastExprToType(Expr, Context.DoubleTy,
+                             CastExpr::CK_FloatingCast);
 
   UsualUnaryConversions(Expr);
 }
@@ -291,9 +290,16 @@ void Sema::DefaultArgumentPromotion(Expr *&Expr) {
 /// will warn if the resulting type is not a POD type, and rejects ObjC
 /// interfaces passed by value.  This returns true if the argument type is
 /// completely illegal.
-bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) {
+bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT,
+                                            FunctionDecl *FDecl) {
   DefaultArgumentPromotion(Expr);
 
+  // __builtin_va_start takes the second argument as a "varargs" argument, but
+  // it doesn't actually do anything with it.  It doesn't need to be non-pod
+  // etc.
+  if (FDecl && FDecl->getBuiltinID() == Builtin::BI__builtin_va_start)
+    return false;
+  
   if (Expr->getType()->isObjCObjectType() &&
       DiagRuntimeBehavior(Expr->getLocStart(),
         PDiag(diag::err_cannot_pass_objc_interface_to_vararg)
@@ -3478,9 +3484,9 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
   // If this is a variadic call, handle args passed through "...".
   if (CallType != VariadicDoesNotApply) {
     // Promote the arguments (C99 6.5.2.2p7).
-    for (unsigned i = ArgIx; i < NumArgs; i++) {
+    for (unsigned i = ArgIx; i != NumArgs; ++i) {
       Expr *Arg = Args[i];
-      Invalid |= DefaultVariadicArgumentPromotion(Arg, CallType);
+      Invalid |= DefaultVariadicArgumentPromotion(Arg, CallType, FDecl);
       AllArgs.push_back(Arg);
     }
   }
index fd4feedf9245b912e04f597a46dc83895d28c912..0b058be579a502bcfcd149f54ae678c2c5b02525 100644 (file)
@@ -254,7 +254,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
       if (Args[i]->isTypeDependent())
         continue;
 
-      IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
+      IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, 0);
     }
   } else {
     // Check for extra arguments to non-variadic methods.
index bf4e7f74ad9b2f1532b0e5dbdec72b156b7f36ed..15f19723f8960a1909cbad06f02d3a0c31926130 100644 (file)
@@ -7054,7 +7054,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
     // Promote the arguments (C99 6.5.2.2p7).
     for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
       Expr *Arg = Args[i];
-      IsError |= DefaultVariadicArgumentPromotion(Arg, VariadicMethod);
+      IsError |= DefaultVariadicArgumentPromotion(Arg, VariadicMethod, 0);
       TheCall->setArg(i + 1, Arg);
     }
   }
index d31f1f7196aa52a3ee996dad69d0549293127dd0..f56d527c377370290bd52d7bdb386b4bf93228f4 100644 (file)
@@ -88,3 +88,12 @@ void test_typeid(Base &base) {
   (void)typeid(get_base(base)); // expected-warning{{cannot pass object of non-POD type 'Base' through variadic function; call will abort at runtime}}
   (void)typeid(eat_base(base)); // okay
 }
+
+
+// rdar://7985267 - Shouldn't warn, doesn't actually use __builtin_va_start is
+// magic.
+
+void t6(Foo somearg, ... ) {
+  __builtin_va_start(0/*valist*/, somearg);
+}
+