зеркало из https://github.com/microsoft/clang-1.git
Use a single function for doing vararg argument promotion. Also, make sure to do the promotion before checking the type - fixes PR3340.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62323 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
636c5ef657
Коммит
dce5e2cabf
|
@ -1523,6 +1523,17 @@ public:
|
|||
// do not have a prototype. Integer promotions are performed on each
|
||||
// argument, and arguments that have type float are promoted to double.
|
||||
void DefaultArgumentPromotion(Expr *&Expr);
|
||||
|
||||
// Used for emitting the right warning by DefaultVariadicArgumentPromotion
|
||||
enum VariadicCallType {
|
||||
VariadicFunction,
|
||||
VariadicBlock,
|
||||
VariadicMethod
|
||||
};
|
||||
|
||||
// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
|
||||
// will warn if the resulting type is not a POD type.
|
||||
void DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT);
|
||||
|
||||
// UsualArithmeticConversions - performs the UsualUnaryConversions on it's
|
||||
// operands and then handles various conversions that are common to binary
|
||||
|
|
|
@ -87,6 +87,21 @@ void Sema::DefaultArgumentPromotion(Expr *&Expr) {
|
|||
UsualUnaryConversions(Expr);
|
||||
}
|
||||
|
||||
// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
|
||||
// will warn if the resulting type is not a POD type.
|
||||
void Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT)
|
||||
|
||||
{
|
||||
DefaultArgumentPromotion(Expr);
|
||||
|
||||
if (!Expr->getType()->isPODType()) {
|
||||
Diag(Expr->getLocStart(),
|
||||
diag::warn_cannot_pass_non_pod_arg_to_vararg) <<
|
||||
Expr->getType() << CT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// UsualArithmeticConversions - Performs various conversions that are common to
|
||||
/// binary operators (C99 6.3.1.8). If both operands aren't arithmetic, this
|
||||
/// routine returns the first non-arithmetic type found. The client is
|
||||
|
@ -1703,21 +1718,16 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
|
|||
|
||||
// If this is a variadic call, handle args passed through "...".
|
||||
if (Proto->isVariadic()) {
|
||||
VariadicCallType CallType = VariadicFunction;
|
||||
if (Fn->getType()->isBlockPointerType())
|
||||
CallType = VariadicBlock; // Block
|
||||
else if (isa<MemberExpr>(Fn))
|
||||
CallType = VariadicMethod;
|
||||
|
||||
// Promote the arguments (C99 6.5.2.2p7).
|
||||
for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
|
||||
Expr *Arg = Args[i];
|
||||
if (!Arg->getType()->isPODType()) {
|
||||
int CallType = 0;
|
||||
if (Fn->getType()->isBlockPointerType())
|
||||
CallType = 1; // Block
|
||||
else if (isa<MemberExpr>(Fn))
|
||||
CallType = 2;
|
||||
|
||||
Diag(Arg->getLocStart(),
|
||||
diag::warn_cannot_pass_non_pod_arg_to_vararg) <<
|
||||
Arg->getType() << CallType;
|
||||
}
|
||||
DefaultArgumentPromotion(Arg);
|
||||
DefaultVariadicArgumentPromotion(Arg, CallType);
|
||||
Call->setArg(i, Arg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,15 +156,8 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
|
|||
|
||||
// Promote additional arguments to variadic methods.
|
||||
if (Method->isVariadic()) {
|
||||
for (unsigned i = NumNamedArgs; i < NumArgs; ++i) {
|
||||
if (!Args[i]->getType()->isPODType()) {
|
||||
Diag(Args[i]->getLocStart(),
|
||||
diag::warn_cannot_pass_non_pod_arg_to_vararg) <<
|
||||
Args[i]->getType() << 2; // Method
|
||||
}
|
||||
|
||||
DefaultArgumentPromotion(Args[i]);
|
||||
}
|
||||
for (unsigned i = NumNamedArgs; i < NumArgs; ++i)
|
||||
DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
|
||||
} else {
|
||||
// Check for extra arguments to non-variadic methods.
|
||||
if (NumArgs != NumNamedArgs) {
|
||||
|
|
|
@ -3624,14 +3624,8 @@ 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];
|
||||
|
||||
if (!Arg->getType()->isPODType()) {
|
||||
Diag(Arg->getLocStart(),
|
||||
diag::warn_cannot_pass_non_pod_arg_to_vararg) <<
|
||||
Arg->getType() << 2; // Method
|
||||
}
|
||||
|
||||
DefaultArgumentPromotion(Arg);
|
||||
DefaultVariadicArgumentPromotion(Arg, VariadicMethod);
|
||||
TheCall->setArg(i + 1, Arg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// RUN: clang -fsyntax-only -verify -fblocks %s
|
||||
|
||||
extern char version[];
|
||||
|
||||
class C {
|
||||
public:
|
||||
C(int);
|
||||
|
@ -14,6 +16,7 @@ void t1()
|
|||
C c(10);
|
||||
|
||||
g(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic function; call will abort at runtime}}
|
||||
g(10, version);
|
||||
}
|
||||
|
||||
void t2()
|
||||
|
@ -21,8 +24,10 @@ void t2()
|
|||
C c(10);
|
||||
|
||||
c.g(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}}
|
||||
c.g(10, version);
|
||||
|
||||
C::h(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic function; call will abort at runtime}}
|
||||
C::h(10, version);
|
||||
}
|
||||
|
||||
int (^block)(int, ...);
|
||||
|
@ -32,6 +37,7 @@ void t3()
|
|||
C c(10);
|
||||
|
||||
block(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic block; call will abort at runtime}}
|
||||
block(10, version);
|
||||
}
|
||||
|
||||
class D {
|
||||
|
@ -46,4 +52,5 @@ void t4()
|
|||
D d;
|
||||
|
||||
d(10, c); // expected-warning{{Line 48: cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}}
|
||||
d(10, version);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// RUN: clang -fsyntax-only -verify %s
|
||||
|
||||
extern char version[];
|
||||
|
||||
class C {
|
||||
public:
|
||||
C(int);
|
||||
|
@ -14,5 +16,6 @@ void t1(D *d)
|
|||
C c(10);
|
||||
|
||||
[d g:10, c]; // expected-warning{{cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}}
|
||||
[d g:10, version];
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче