forked from OSchip/llvm-project
Fix two bugs exposed by array passing assert:
(1) Additional arguments to variadic methods should have default promotions applied. (2) Additional arguments to non-variadic methods were allowed. llvm-svn: 56084
This commit is contained in:
parent
16211a2cc7
commit
ce05c8eb49
|
@ -965,7 +965,7 @@ private:
|
|||
/// \param Method - May be null.
|
||||
/// \param [out] ReturnType - The return type of the send.
|
||||
/// \return true iff there were any incompatible types.
|
||||
bool CheckMessageArgumentTypes(Expr **Args, Selector Sel,
|
||||
bool CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Selector Sel,
|
||||
ObjCMethodDecl *Method, const char *PrefixStr,
|
||||
SourceLocation lbrac, SourceLocation rbrac,
|
||||
QualType &ReturnType);
|
||||
|
|
|
@ -107,12 +107,11 @@ Sema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
|
|||
return new ObjCProtocolExpr(t, PDecl, AtLoc, RParenLoc);
|
||||
}
|
||||
|
||||
bool Sema::CheckMessageArgumentTypes(Expr **Args, Selector Sel,
|
||||
ObjCMethodDecl *Method,
|
||||
bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
|
||||
Selector Sel, ObjCMethodDecl *Method,
|
||||
const char *PrefixStr,
|
||||
SourceLocation lbrac, SourceLocation rbrac,
|
||||
QualType &ReturnType) {
|
||||
unsigned NumArgs = Sel.getNumArgs();
|
||||
if (!Method) {
|
||||
// Apply default argument promotion as for (C99 6.5.2.2p6).
|
||||
for (unsigned i = 0; i != NumArgs; i++)
|
||||
|
@ -126,8 +125,11 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, Selector Sel,
|
|||
ReturnType = Method->getResultType();
|
||||
}
|
||||
|
||||
unsigned NumNamedArgs = Sel.getNumArgs();
|
||||
assert(NumArgs >= NumNamedArgs && "Too few arguments for selector!");
|
||||
|
||||
bool anyIncompatibleArgs = false;
|
||||
for (unsigned i = 0; i < NumArgs; i++) {
|
||||
for (unsigned i = 0; i < NumNamedArgs; i++) {
|
||||
Expr *argExpr = Args[i];
|
||||
assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
|
||||
|
||||
|
@ -149,6 +151,22 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, Selector Sel,
|
|||
DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType,
|
||||
argExpr, "sending");
|
||||
}
|
||||
|
||||
// Promote additional arguments to variadic methods.
|
||||
if (Method->isVariadic()) {
|
||||
for (unsigned i = NumNamedArgs; i < NumArgs; ++i)
|
||||
DefaultArgumentPromotion(Args[i]);
|
||||
} else {
|
||||
// Check for extra arguments to non-variadic methods.
|
||||
if (NumArgs != NumNamedArgs) {
|
||||
Diag(Args[NumNamedArgs]->getLocStart(),
|
||||
diag::err_typecheck_call_too_many_args,
|
||||
Method->getSourceRange(),
|
||||
SourceRange(Args[NumNamedArgs]->getLocStart(),
|
||||
Args[NumArgs-1]->getLocEnd()));
|
||||
}
|
||||
}
|
||||
|
||||
return anyIncompatibleArgs;
|
||||
}
|
||||
|
||||
|
@ -220,7 +238,7 @@ Sema::ExprResult Sema::ActOnClassMessage(
|
|||
if (!Method)
|
||||
Method = ClassDecl->lookupInstanceMethod(Sel);
|
||||
|
||||
if (CheckMessageArgumentTypes(ArgExprs, Sel, Method, "+",
|
||||
if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, "+",
|
||||
lbrac, rbrac, returnType))
|
||||
return true;
|
||||
|
||||
|
@ -259,7 +277,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
|
|||
ObjCMethodDecl *Method = InstanceMethodPool[Sel].Method;
|
||||
if (!Method)
|
||||
Method = FactoryMethodPool[Sel].Method;
|
||||
if (CheckMessageArgumentTypes(ArgExprs, Sel, Method, "-",
|
||||
if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, "-",
|
||||
lbrac, rbrac, returnType))
|
||||
return true;
|
||||
return new ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, rbrac,
|
||||
|
@ -280,7 +298,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
|
|||
Method = FactoryMethodPool[Sel].Method;
|
||||
if (!Method)
|
||||
Method = InstanceMethodPool[Sel].Method;
|
||||
if (CheckMessageArgumentTypes(ArgExprs, Sel, Method, "-",
|
||||
if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, "-",
|
||||
lbrac, rbrac, returnType))
|
||||
return true;
|
||||
return new ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, rbrac,
|
||||
|
@ -344,7 +362,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
|
|||
if (!Method)
|
||||
Method = InstanceMethodPool[Sel].Method;
|
||||
}
|
||||
if (CheckMessageArgumentTypes(ArgExprs, Sel, Method, "-",
|
||||
if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, "-",
|
||||
lbrac, rbrac, returnType))
|
||||
return true;
|
||||
return new ObjCMessageExpr(RExpr, Sel, returnType, Method, lbrac, rbrac,
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// RUN: clang -emit-llvm -o %t %s
|
||||
|
||||
void f0(id a) {
|
||||
// This should have an implicit cast
|
||||
[ a print: "hello" ];
|
||||
}
|
||||
|
||||
@interface A
|
||||
-(void) m: (int) arg0, ...;
|
||||
@end
|
||||
|
||||
int f1(A *a) {
|
||||
// This should also get an implicit cast (for the vararg)
|
||||
[a m: 1, "test"];
|
||||
}
|
|
@ -61,3 +61,10 @@ extern Class NSClassFromObject(id object);
|
|||
}
|
||||
@end
|
||||
|
||||
@interface I0
|
||||
-(void) nonVararg: (int) x;
|
||||
@end
|
||||
|
||||
int f0(I0 *ob) {
|
||||
[ ob nonVararg: 0, 1, 2]; // expected-error {{too many arguments to function}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue