From: Douglas Gregor Date: Tue, 13 Jan 2009 05:10:00 +0000 (+0000) Subject: Fix argument-passing bugs in a call to object X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=518fda1d121dcba3ad7276f5e9a94f733f6e5ecd;p=clang Fix argument-passing bugs in a call to object git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62147 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index be1a27e5c6..c66db173eb 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -3542,25 +3542,31 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, ResultTy, RParenLoc)); delete [] MethodArgs; + // We may have default arguments. If so, we need to allocate more + // slots in the call for them. + if (NumArgs < NumArgsInProto) + TheCall->setNumArgs(NumArgsInProto + 1); + else if (NumArgs > NumArgsInProto) + NumArgsToCheck = NumArgsInProto; + // Initialize the implicit object parameter. - if (!PerformObjectArgumentInitialization(Object, Method)) + if (PerformObjectArgumentInitialization(Object, Method)) return true; TheCall->setArg(0, Object); // Check the argument types. for (unsigned i = 0; i != NumArgsToCheck; i++) { - QualType ProtoArgType = Proto->getArgType(i); - Expr *Arg; - if (i < NumArgs) + if (i < NumArgs) { Arg = Args[i]; - else + + // Pass the argument. + QualType ProtoArgType = Proto->getArgType(i); + if (PerformCopyInitialization(Arg, ProtoArgType, "passing")) + return true; + } else { Arg = new CXXDefaultArgExpr(Method->getParamDecl(i)); - QualType ArgType = Arg->getType(); - - // Pass the argument. - if (PerformCopyInitialization(Arg, ProtoArgType, "passing")) - return true; + } TheCall->setArg(i + 1, Arg); } diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp index d8be6bca49..e558faa880 100644 --- a/test/SemaCXX/overloaded-operator.cpp +++ b/test/SemaCXX/overloaded-operator.cpp @@ -124,17 +124,29 @@ void test_comma(X x, Y y) { X& xr = (x, x); } - struct Callable { int& operator()(int, double = 2.71828); // expected-note{{candidate function}} float& operator()(int, double, long, ...); // expected-note{{candidate function}} + + double& operator()(float); // expected-note{{candidate function}} +}; + +struct Callable2 { + int& operator()(int i = 0); + double& operator()(...) const; }; -void test_callable(Callable c) { +void test_callable(Callable c, Callable2 c2, const Callable2& c2c) { int &ir = c(1); float &fr = c(1, 3.14159, 17, 42); c(); // expected-error{{no matching function for call to object of type 'struct Callable'; candidates are:}} + + double &dr = c(1.0f); + + int &ir2 = c2(); + int &ir3 = c2(1); + double &fr2 = c2c(); } typedef float FLOAT; diff --git a/test/SemaCXX/qualified-id-lookup.cpp b/test/SemaCXX/qualified-id-lookup.cpp index c0d1ca370d..cbc197ddc7 100644 --- a/test/SemaCXX/qualified-id-lookup.cpp +++ b/test/SemaCXX/qualified-id-lookup.cpp @@ -33,6 +33,10 @@ namespace N { namespace N { struct f1 { static int member; + + typedef int type; + + void foo(type); }; void test_f1() { @@ -40,8 +44,13 @@ namespace N { } } +void N::f1::foo(int) { } + namespace N { - float& f1(int); + float& f1(int x) { + N::f1::type& i1 = x; + // FIXME: currently fails f1::type& i2 = x; + } struct f2 { static int member;