]> granicus.if.org Git - clang/commitdiff
When performing template argument deduction against a template-id,
authorDouglas Gregor <dgregor@apple.com>
Tue, 2 Nov 2010 00:02:34 +0000 (00:02 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 2 Nov 2010 00:02:34 +0000 (00:02 +0000)
only keep deduction results for successful deductions, so that they
can be compared against each other. Fixes PR8462, from Richard Smith!

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117983 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateDeduction.cpp
test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp

index 855516cf10cc5aa1b82bcdc1c6ecd8aab28918a3..905e17e9c149396f728a9e8420e77c4a9d32332f 100644 (file)
@@ -721,6 +721,8 @@ DeduceTemplateArguments(Sema &S,
           llvm::SmallVector<const RecordType *, 8> ToVisit;
           ToVisit.push_back(RecordT);
           bool Successful = false;
+          llvm::SmallVectorImpl<DeducedTemplateArgument> DeducedOrig(0);
+          DeducedOrig = Deduced;
           while (!ToVisit.empty()) {
             // Retrieve the next class in the inheritance hierarchy.
             const RecordType *NextT = ToVisit.back();
@@ -738,9 +740,14 @@ DeduceTemplateArguments(Sema &S,
                                           QualType(NextT, 0), Info, Deduced);
 
               // If template argument deduction for this base was successful,
-              // note that we had some success.
-              if (BaseResult == Sema::TDK_Success)
+              // note that we had some success. Otherwise, ignore any deductions
+              // from this base class.
+              if (BaseResult == Sema::TDK_Success) {
                 Successful = true;
+                DeducedOrig = Deduced;
+              }
+              else
+                Deduced = DeducedOrig;
             }
 
             // Visit base classes
index 19962c534909f99a390aa78e2a6d8313664db902..3c22cf349c9f73bdc09d3295b1b13a95513bcef1 100644 (file)
@@ -101,3 +101,25 @@ void test_f4(D d, E e, F f, G g) {
   C<int, 1> *ci3c = f4c(&g);
   int       *ip1 = f4c(&f);
 }
+
+// PR8462
+namespace N {
+  struct T0;
+  struct T1;
+
+  template<typename X, typename Y> struct B {};
+
+  struct J : B<T0,T0> {};
+  struct K : B<T1,T1> {};
+
+  struct D : J, K {};
+
+  template<typename X, typename Y> void F(B<Y,X>);
+
+  void test()
+  {
+    D d; 
+    N::F<T0>(d); // Fails
+    N::F<T1>(d); // OK
+  }
+}