When performing template argument deduction for a non-reference
authorDouglas Gregor <dgregor@apple.com>
Sun, 6 Mar 2011 09:03:20 +0000 (09:03 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sun, 6 Mar 2011 09:03:20 +0000 (09:03 +0000)
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

lib/Sema/SemaTemplateDeduction.cpp
test/SemaCXX/conversion-function.cpp

index 43cbd62a6351cf23d7263a451862ef61487c3377..c30c8a061622963939b231fa7ae7da7398f1add9 100644 (file)
@@ -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<ReferenceType>())
     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<ReferenceType>())
-    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();
   }
 
index 61c8ada62fb3f4d485fad977c33bf21107e0f39a..aa47ae0f4825550e0d3cf7567cb9c55c6dfdb800 100644 (file)
@@ -353,3 +353,28 @@ namespace PR8034 {
   };
   int x = C().operator int();
 }
+
+namespace PR9336 {
+  template<class T>
+  struct generic_list
+  {
+    template<class Container>
+    operator Container()
+    { 
+      Container ar;
+      T* i;
+      ar[0]=*i;
+      return ar;
+    }
+  };
+
+  template<class T>
+  struct array
+  {
+    T& operator[](int);
+    const T& operator[](int)const;
+  };
+
+  generic_list<generic_list<int> > l;
+  array<array<int> > a = l;
+}