]> granicus.if.org Git - clang/commitdiff
When template deduction fails on a derived class, try a template deduction on
authorRichard Trieu <rtrieu@google.com>
Wed, 7 Nov 2012 21:17:13 +0000 (21:17 +0000)
committerRichard Trieu <rtrieu@google.com>
Wed, 7 Nov 2012 21:17:13 +0000 (21:17 +0000)
the base class.  If the base class deduction succeeds, use those results.  If
it fails, keep using the results from the derived class template deduction.

This prevents an assertion later where the type of deduction failure doesn't
match up with the template deduction info.

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

lib/Sema/SemaTemplateDeduction.cpp
test/SemaTemplate/derived.cpp [new file with mode: 0644]

index 98e22c0b65e0b36ac49fedcf6cd18eed43744936..bf4533d6998caf4757d7a87894086141bfe154c4 100644 (file)
@@ -1393,9 +1393,11 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
             // If this is a base class, try to perform template argument
             // deduction from it.
             if (NextT != RecordT) {
+              TemplateDeductionInfo BaseInfo(Info.getLocation());
               Sema::TemplateDeductionResult BaseResult
                 = DeduceTemplateArguments(S, TemplateParams, SpecParam,
-                                          QualType(NextT, 0), Info, Deduced);
+                                          QualType(NextT, 0), BaseInfo,
+                                          Deduced);
 
               // If template argument deduction for this base was successful,
               // note that we had some success. Otherwise, ignore any deductions
@@ -1404,6 +1406,9 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
                 Successful = true;
                 DeducedOrig.clear();
                 DeducedOrig.append(Deduced.begin(), Deduced.end());
+                Info.Param = BaseInfo.Param;
+                Info.FirstArg = BaseInfo.FirstArg;
+                Info.SecondArg = BaseInfo.SecondArg;
               }
               else
                 Deduced = DeducedOrig;
diff --git a/test/SemaTemplate/derived.cpp b/test/SemaTemplate/derived.cpp
new file mode 100644 (file)
index 0000000..1fb9401
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> class vector2 {};
+template<typename T> class vector : vector2<T> {};
+
+template<typename T> void Foo2(vector2<const T*> V) {}  // expected-note{{candidate template ignored: can't deduce a type for 'T' which would make 'const T' equal 'int'}}
+template<typename T> void Foo(vector<const T*> V) {} // expected-note {{candidate template ignored: can't deduce a type for 'T' which would make 'const T' equal 'int'}}
+
+void test() {
+  Foo2(vector2<int*>());  // expected-error{{no matching function for call to 'Foo2'}}
+  Foo(vector<int*>());  // expected-error{{no matching function for call to 'Foo'}}
+}