implement rdar://6780761, making sema reject some code that otherwise

crashes codegen.

llvm-svn: 68891
This commit is contained in:
Chris Lattner 2009-04-12 08:11:20 +00:00
parent ce6bcf0847
commit a8a7d0f371
6 changed files with 41 additions and 19 deletions

View File

@ -1190,6 +1190,11 @@ def err_typecheck_call_too_many_args : Error<
def warn_call_wrong_number_of_arguments : Warning< def warn_call_wrong_number_of_arguments : Warning<
"too %select{few|many}0 arguments in call to %1">; "too %select{few|many}0 arguments in call to %1">;
def err_deleted_function_use : Error<"attempt to use a deleted function">; def err_deleted_function_use : Error<"attempt to use a deleted function">;
def err_cannot_pass_objc_interface_to_vararg : Error<
"cannot pass object with interface type %0 by-value through variadic "
"%select{function|block|method}1">;
def warn_cannot_pass_non_pod_arg_to_vararg : Warning< def warn_cannot_pass_non_pod_arg_to_vararg : Warning<
"cannot pass object of non-POD type %0 through variadic " "cannot pass object of non-POD type %0 through variadic "
"%select{function|block|method}1; call will abort at runtime">; "%select{function|block|method}1; call will abort at runtime">;

View File

@ -2210,7 +2210,7 @@ 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.
void DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT); bool DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT);
// 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

View File

@ -154,16 +154,25 @@ void Sema::DefaultArgumentPromotion(Expr *&Expr) {
UsualUnaryConversions(Expr); UsualUnaryConversions(Expr);
} }
// 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, and rejects ObjC
void Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) { /// interfaces passed by value. This returns true if the argument type is
/// completely illegal.
bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) {
DefaultArgumentPromotion(Expr); DefaultArgumentPromotion(Expr);
if (!Expr->getType()->isPODType()) { if (Expr->getType()->isObjCInterfaceType()) {
Diag(Expr->getLocStart(), Diag(Expr->getLocStart(),
diag::warn_cannot_pass_non_pod_arg_to_vararg) << diag::err_cannot_pass_objc_interface_to_vararg)
Expr->getType() << CT; << Expr->getType() << CT;
return true;
} }
if (!Expr->getType()->isPODType())
Diag(Expr->getLocStart(), diag::warn_cannot_pass_non_pod_arg_to_vararg)
<< Expr->getType() << CT;
return false;
} }
@ -2223,7 +2232,7 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
// 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];
DefaultVariadicArgumentPromotion(Arg, CallType); Invalid |= DefaultVariadicArgumentPromotion(Arg, CallType);
Call->setArg(i, Arg); Call->setArg(i, Arg);
} }
} }

View File

@ -164,7 +164,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
unsigned NumNamedArgs = Sel.getNumArgs(); unsigned NumNamedArgs = Sel.getNumArgs();
assert(NumArgs >= NumNamedArgs && "Too few arguments for selector!"); assert(NumArgs >= NumNamedArgs && "Too few arguments for selector!");
bool anyIncompatibleArgs = false; bool IsError = false;
for (unsigned i = 0; i < NumNamedArgs; i++) { for (unsigned i = 0; i < NumNamedArgs; i++) {
Expr *argExpr = Args[i]; Expr *argExpr = Args[i];
assert(argExpr && "CheckMessageArgumentTypes(): missing expression"); assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
@ -183,7 +183,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
if (Args[i] != argExpr) // The expression was converted. if (Args[i] != argExpr) // The expression was converted.
Args[i] = argExpr; // Make sure we store the converted expression. Args[i] = argExpr; // Make sure we store the converted expression.
anyIncompatibleArgs |= IsError |=
DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType, DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType,
argExpr, "sending"); argExpr, "sending");
} }
@ -191,7 +191,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
// Promote additional arguments to variadic methods. // Promote additional arguments to variadic methods.
if (Method->isVariadic()) { if (Method->isVariadic()) {
for (unsigned i = NumNamedArgs; i < NumArgs; ++i) for (unsigned i = NumNamedArgs; i < NumArgs; ++i)
DefaultVariadicArgumentPromotion(Args[i], VariadicMethod); IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
} else { } else {
// Check for extra arguments to non-variadic methods. // Check for extra arguments to non-variadic methods.
if (NumArgs != NumNamedArgs) { if (NumArgs != NumNamedArgs) {
@ -203,7 +203,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
} }
} }
return anyIncompatibleArgs; return IsError;
} }
bool Sema::isSelfExpr(Expr *RExpr) { bool Sema::isSelfExpr(Expr *RExpr) {

View File

@ -4178,11 +4178,13 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
else if (NumArgs > NumArgsInProto) else if (NumArgs > NumArgsInProto)
NumArgsToCheck = NumArgsInProto; NumArgsToCheck = NumArgsInProto;
bool IsError = false;
// Initialize the implicit object parameter. // Initialize the implicit object parameter.
if (PerformObjectArgumentInitialization(Object, Method)) IsError |= PerformObjectArgumentInitialization(Object, Method);
return true;
TheCall->setArg(0, Object); TheCall->setArg(0, Object);
// Check the argument types. // Check the argument types.
for (unsigned i = 0; i != NumArgsToCheck; i++) { for (unsigned i = 0; i != NumArgsToCheck; i++) {
Expr *Arg; Expr *Arg;
@ -4191,8 +4193,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
// Pass the argument. // Pass the argument.
QualType ProtoArgType = Proto->getArgType(i); QualType ProtoArgType = Proto->getArgType(i);
if (PerformCopyInitialization(Arg, ProtoArgType, "passing")) IsError |= PerformCopyInitialization(Arg, ProtoArgType, "passing");
return true;
} else { } else {
Arg = new (Context) CXXDefaultArgExpr(Method->getParamDecl(i)); Arg = new (Context) CXXDefaultArgExpr(Method->getParamDecl(i));
} }
@ -4205,12 +4206,13 @@ 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);
DefaultVariadicArgumentPromotion(Arg, VariadicMethod);
TheCall->setArg(i + 1, Arg); TheCall->setArg(i + 1, Arg);
} }
} }
if (IsError) return true;
return CheckFunctionCall(Method, TheCall.take()).release(); return CheckFunctionCall(Method, TheCall.take()).release();
} }

View File

@ -22,3 +22,9 @@
void somefunc(foo x) {} // expected-error {{Objective-C interface type 'foo' cannot be passed by value}} void somefunc(foo x) {} // expected-error {{Objective-C interface type 'foo' cannot be passed by value}}
foo somefunc2() {} // expected-error {{Objective-C interface type 'foo' cannot be returned by value}} foo somefunc2() {} // expected-error {{Objective-C interface type 'foo' cannot be returned by value}}
// rdar://6780761
void f0(foo *a0) {
extern void g0(int x, ...);
g0(1, *(foo*)0); // expected-error {{cannot pass object with interface type 'foo' by-value through variadic function}}
}