forked from OSchip/llvm-project
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
This commit is contained in:
parent
298e6b82eb
commit
bb53efb016
|
@ -4093,7 +4093,8 @@ public:
|
||||||
|
|
||||||
// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
|
// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
|
||||||
// will warn if the resulting type is not a POD type.
|
// 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
|
// UsualArithmeticConversions - performs the UsualUnaryConversions on it's
|
||||||
// operands and then handles various conversions that are common to binary
|
// operands and then handles various conversions that are common to binary
|
||||||
|
|
|
@ -279,10 +279,9 @@ void Sema::DefaultArgumentPromotion(Expr *&Expr) {
|
||||||
assert(!Ty.isNull() && "DefaultArgumentPromotion - missing type");
|
assert(!Ty.isNull() && "DefaultArgumentPromotion - missing type");
|
||||||
|
|
||||||
// If this is a 'float' (CVR qualified or typedef) promote to double.
|
// If this is a 'float' (CVR qualified or typedef) promote to double.
|
||||||
if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
|
if (Ty->isSpecificBuiltinType(BuiltinType::Float))
|
||||||
if (BT->getKind() == BuiltinType::Float)
|
return ImpCastExprToType(Expr, Context.DoubleTy,
|
||||||
return ImpCastExprToType(Expr, Context.DoubleTy,
|
CastExpr::CK_FloatingCast);
|
||||||
CastExpr::CK_FloatingCast);
|
|
||||||
|
|
||||||
UsualUnaryConversions(Expr);
|
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
|
/// 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
|
/// interfaces passed by value. This returns true if the argument type is
|
||||||
/// completely illegal.
|
/// completely illegal.
|
||||||
bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) {
|
bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT,
|
||||||
|
FunctionDecl *FDecl) {
|
||||||
DefaultArgumentPromotion(Expr);
|
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() &&
|
if (Expr->getType()->isObjCObjectType() &&
|
||||||
DiagRuntimeBehavior(Expr->getLocStart(),
|
DiagRuntimeBehavior(Expr->getLocStart(),
|
||||||
PDiag(diag::err_cannot_pass_objc_interface_to_vararg)
|
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 this is a variadic call, handle args passed through "...".
|
||||||
if (CallType != VariadicDoesNotApply) {
|
if (CallType != VariadicDoesNotApply) {
|
||||||
// Promote the arguments (C99 6.5.2.2p7).
|
// 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];
|
Expr *Arg = Args[i];
|
||||||
Invalid |= DefaultVariadicArgumentPromotion(Arg, CallType);
|
Invalid |= DefaultVariadicArgumentPromotion(Arg, CallType, FDecl);
|
||||||
AllArgs.push_back(Arg);
|
AllArgs.push_back(Arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,7 +254,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
|
||||||
if (Args[i]->isTypeDependent())
|
if (Args[i]->isTypeDependent())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
|
IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Check for extra arguments to non-variadic methods.
|
// Check for extra arguments to non-variadic methods.
|
||||||
|
|
|
@ -7054,7 +7054,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
|
||||||
// Promote the arguments (C99 6.5.2.2p7).
|
// Promote the arguments (C99 6.5.2.2p7).
|
||||||
for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
|
for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
|
||||||
Expr *Arg = Args[i];
|
Expr *Arg = Args[i];
|
||||||
IsError |= DefaultVariadicArgumentPromotion(Arg, VariadicMethod);
|
IsError |= DefaultVariadicArgumentPromotion(Arg, VariadicMethod, 0);
|
||||||
TheCall->setArg(i + 1, Arg);
|
TheCall->setArg(i + 1, Arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(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
|
(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue