From: Douglas Gregor Date: Sun, 6 Mar 2011 09:03:20 +0000 (+0000) Subject: When performing template argument deduction for a non-reference X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5453d93ab8668f2d9d0bc02182695b02d207e32d;p=clang When performing template argument deduction for a non-reference conversion function when we're binding the result to a reference, drop cv-qualifiers on the type we're referring to, since we should be deducing a type that can be adjusted (via cv-qualification) to the requested type. Fixes PR9336, and the remaining Boost.Assign failure. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127117 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 43cbd62a63..c30c8a0616 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -2845,18 +2845,18 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, QualType P = Context.getCanonicalType(FromType); QualType A = Context.getCanonicalType(ToType); - // C++0x [temp.deduct.conv]p3: + // C++0x [temp.deduct.conv]p2: // If P is a reference type, the type referred to by P is used for // type deduction. if (const ReferenceType *PRef = P->getAs()) P = PRef->getPointeeType(); - // C++0x [temp.deduct.conv]p3: - // If A is a reference type, the type referred to by A is used + // C++0x [temp.deduct.conv]p4: + // [...] If A is a reference type, the type referred to by A is used // for type deduction. if (const ReferenceType *ARef = A->getAs()) - A = ARef->getPointeeType(); - // C++ [temp.deduct.conv]p2: + A = ARef->getPointeeType().getUnqualifiedType(); + // C++ [temp.deduct.conv]p3: // // If A is not a reference type: else { @@ -2877,9 +2877,10 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, else P = P.getUnqualifiedType(); - // C++0x [temp.deduct.conv]p3: + // C++0x [temp.deduct.conv]p4: // If A is a cv-qualified type, the top level cv-qualifiers of A's - // type are ignored for type deduction. + // type are ignored for type deduction. If A is a reference type, the type + // referred to by A is used for type deduction. A = A.getUnqualifiedType(); } diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp index 61c8ada62f..aa47ae0f48 100644 --- a/test/SemaCXX/conversion-function.cpp +++ b/test/SemaCXX/conversion-function.cpp @@ -353,3 +353,28 @@ namespace PR8034 { }; int x = C().operator int(); } + +namespace PR9336 { + template + struct generic_list + { + template + operator Container() + { + Container ar; + T* i; + ar[0]=*i; + return ar; + } + }; + + template + struct array + { + T& operator[](int); + const T& operator[](int)const; + }; + + generic_list > l; + array > a = l; +}