Make sure we perform the variadic method check correctly for calls to a member operator(). PR14057.
llvm-svn: 165678
This commit is contained in:
parent
60a25a571e
commit
726d11c41b
|
@ -542,11 +542,23 @@ void Sema::CheckConstructorCall(FunctionDecl *FDecl, Expr **Args,
|
|||
/// and safety properties not strictly enforced by the C type system.
|
||||
bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,
|
||||
const FunctionProtoType *Proto) {
|
||||
bool IsMemberFunction = isa<CXXMemberCallExpr>(TheCall);
|
||||
bool IsMemberOperatorCall = isa<CXXOperatorCallExpr>(TheCall) &&
|
||||
isa<CXXMethodDecl>(FDecl);
|
||||
bool IsMemberFunction = isa<CXXMemberCallExpr>(TheCall) ||
|
||||
IsMemberOperatorCall;
|
||||
VariadicCallType CallType = getVariadicCallType(FDecl, Proto,
|
||||
TheCall->getCallee());
|
||||
unsigned NumProtoArgs = Proto ? Proto->getNumArgs() : 0;
|
||||
checkCall(FDecl, TheCall->getArgs(), TheCall->getNumArgs(), NumProtoArgs,
|
||||
Expr** Args = TheCall->getArgs();
|
||||
unsigned NumArgs = TheCall->getNumArgs();
|
||||
if (isa<CXXOperatorCallExpr>(TheCall) && isa<CXXMethodDecl>(FDecl)) {
|
||||
// If this is a call to a member operator, hide the first argument
|
||||
// from checkCall.
|
||||
// FIXME: Our choice of AST representation here is less than ideal.
|
||||
++Args;
|
||||
--NumArgs;
|
||||
}
|
||||
checkCall(FDecl, Args, NumArgs, NumProtoArgs,
|
||||
IsMemberFunction, TheCall->getRParenLoc(),
|
||||
TheCall->getCallee()->getSourceRange(), CallType);
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ struct S {
|
|||
expected-error{{out of bounds}}
|
||||
const char* h3(const char*) __attribute__((format_arg(1))); // \
|
||||
expected-error{{invalid for the implicit this argument}}
|
||||
|
||||
void operator() (const char*, ...) __attribute__((format(printf, 2, 3)));
|
||||
};
|
||||
|
||||
// PR5521
|
||||
|
@ -33,3 +35,9 @@ namespace PR8625 {
|
|||
s.f(str, "%s", str);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we interpret member operator calls as having an implicit
|
||||
// this argument.
|
||||
void test_operator_call(S s, const char* str) {
|
||||
s("%s", str);
|
||||
}
|
||||
|
|
|
@ -123,3 +123,21 @@ int t9(int n) {
|
|||
// Make sure the error works in potentially-evaluated sizeof
|
||||
return (int)sizeof(*(Helper(Foo()), (int (*)[n])0)); // expected-warning{{cannot pass object of non-POD type}}
|
||||
}
|
||||
|
||||
// PR14057
|
||||
namespace t10 {
|
||||
struct F {
|
||||
F();
|
||||
};
|
||||
|
||||
struct S {
|
||||
void operator()(F, ...);
|
||||
};
|
||||
|
||||
void foo() {
|
||||
S s;
|
||||
F f;
|
||||
s.operator()(f);
|
||||
s(f);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue