From: Douglas Gregor Date: Wed, 14 Oct 2009 16:50:13 +0000 (+0000) Subject: Implement support for overloaded operator uses that result to a call X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d9842d0e6da0e28b6913b464e37d9a4dc5ec73b9;p=clang Implement support for overloaded operator uses that result to a call to a member operator template. We missed updating this call site when adding support for function templates; bug exposed by a test for PR5072. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84111 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 8c697cc868..99e7b0811c 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -2769,10 +2769,21 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, for (LookupResult::iterator Oper = Operators.begin(), OperEnd = Operators.end(); Oper != OperEnd; - ++Oper) - AddMethodCandidate(cast(*Oper), Args[0], - Args+1, NumArgs - 1, CandidateSet, - /*SuppressUserConversions=*/false); + ++Oper) { + if (CXXMethodDecl *Method = dyn_cast(*Oper)) { + AddMethodCandidate(Method, Args[0], Args+1, NumArgs - 1, CandidateSet, + /*SuppressUserConversions=*/false); + continue; + } + + assert(isa(*Oper) && + isa(cast(*Oper) + ->getTemplatedDecl()) && + "Expected a member function template"); + AddMethodTemplateCandidate(cast(*Oper), false, 0, 0, + Args[0], Args+1, NumArgs - 1, CandidateSet, + /*SuppressUserConversions=*/false); + } } } diff --git a/test/SemaTemplate/copy-ctor-assign.cpp b/test/SemaTemplate/copy-ctor-assign.cpp new file mode 100644 index 0000000000..90fb0133a7 --- /dev/null +++ b/test/SemaTemplate/copy-ctor-assign.cpp @@ -0,0 +1,36 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// Make sure that copy constructors and assignment operators are properly +// generated when there is a matching + +// PR5072 +template +struct X { + template + X(const X& other) + : value(other.value + 1) { } // expected-error{{binary expression}} + + template + X& operator=(const X& other) { + value = other.value + 1; // expected-error{{binary expression}} + return *this; + } + + T value; +}; + +struct Y {}; + +X test0(X x) { return x; } +X test1(X x) { return x; } + + +X test2(X x) { + return x; // expected-note{{instantiation}} +} + +void test3(X &x, X xi, X xl, X xmptr) { + x = xi; + x = xl; + x = xmptr; // expected-note{{instantiation}} +} \ No newline at end of file