// 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
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
// 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);
}
}
// 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) {
// 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);
}
}
// RUN: clang -fsyntax-only -verify -fblocks %s
+extern char version[];
+
class C {
public:
C(int);
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()
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, ...);
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 {
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);
}
// RUN: clang -fsyntax-only -verify %s
+extern char version[];
+
class C {
public:
C(int);
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];
}