summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-05-16 04:01:30 +0000
committerChris Lattner <sabre@nondot.org>2010-05-16 04:01:30 +0000
commitbb53efb016d205d0aeed9cef69c2db51b3f351fc (patch)
tree851d0eb4c2e35b5add85702947a64d83effd40e1
parent298e6b82eb3037c39fc75d082b87d7bca73743cf (diff)
downloadbcm5719-llvm-bb53efb016d205d0aeed9cef69c2db51b3f351fc.tar.gz
bcm5719-llvm-bb53efb016d205d0aeed9cef69c2db51b3f351fc.zip
fix rdar://7985267 - Don't emit an error about a non-pod argument
passed to va_start, it doesn't actually pass it. llvm-svn: 103899
-rw-r--r--clang/lib/Sema/Sema.h3
-rw-r--r--clang/lib/Sema/SemaExpr.cpp20
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp2
-rw-r--r--clang/lib/Sema/SemaOverload.cpp2
-rw-r--r--clang/test/SemaCXX/vararg-non-pod.cpp9
5 files changed, 26 insertions, 10 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index 3e143bb3b00..a7d242c559b 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -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
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 60c716353a9..5a24a2c4c0a 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -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);
}
}
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index fd4feedf924..0b058be579a 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -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.
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index bf4e7f74ad9..15f19723f89 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -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);
}
}
diff --git a/clang/test/SemaCXX/vararg-non-pod.cpp b/clang/test/SemaCXX/vararg-non-pod.cpp
index d31f1f7196a..f56d527c377 100644
--- a/clang/test/SemaCXX/vararg-non-pod.cpp
+++ b/clang/test/SemaCXX/vararg-non-pod.cpp
@@ -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);
+}
+
OpenPOWER on IntegriCloud