]> granicus.if.org Git - clang/commitdiff
Improve template argument deduction in the case where the parameter
authorDouglas Gregor <dgregor@apple.com>
Wed, 30 Sep 2009 22:13:51 +0000 (22:13 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 30 Sep 2009 22:13:51 +0000 (22:13 +0000)
type is a template-id (e.g., basic_ostream<CharT, Traits>) and the
argument type is a class that has a derived class matching the
parameter type. Previously, we were giving up on template argument
deduction too early.

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

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

index 64b7f8b140e166abdcafb57f278854e26d44c04d..b981389d1d15b9f75a6e86d704c0730d7b8c46f1 100644 (file)
@@ -651,8 +651,7 @@ DeduceTemplateArguments(ASTContext &Context,
         = DeduceTemplateArguments(Context, TemplateParams, SpecParam, Arg,
                                   Info, Deduced);
 
-      if (Result && (TDF & TDF_DerivedClass) &&
-          Result != Sema::TDK_Inconsistent) {
+      if (Result && (TDF & TDF_DerivedClass)) {
         // C++ [temp.deduct.call]p3b3:
         //   If P is a class, and P has the form template-id, then A can be a
         //   derived class of the deduced A. Likewise, if P is a pointer to a
@@ -690,11 +689,6 @@ DeduceTemplateArguments(ASTContext &Context,
               // note that we had some success.
               if (BaseResult == Sema::TDK_Success)
                 Successful = true;
-              // If deduction against this base resulted in an inconsistent
-              // set of deduced template arguments, template argument
-              // deduction fails.
-              else if (BaseResult == Sema::TDK_Inconsistent)
-                return BaseResult;
             }
 
             // Visit base classes
index 596427adf9efd6db3044fa7f46007385ee87fa16..dbe2ff3e18fb28980a73716bfaeeab73a2e5bcc9 100644 (file)
@@ -66,6 +66,7 @@ template<typename T, int I> struct C { };
 struct D : public C<int, 1> { };
 struct E : public D { };
 struct F : A<float> { };
+struct G : A<float>, C<int, 1> { };
 
 template<typename T, int I>
   C<T, I> *f4a(const C<T, I>&);
@@ -75,12 +76,13 @@ template<typename T, int I>
   C<T, I> *f4c(C<T, I>*);
 int *f4c(...);
 
-void test_f4(D d, E e, F f) {
+void test_f4(D d, E e, F f, G g) {
   C<int, 1> *ci1a = f4a(d);
   C<int, 1> *ci2a = f4a(e);
   C<int, 1> *ci1b = f4b(d);
   C<int, 1> *ci2b = f4b(e);
   C<int, 1> *ci1c = f4c(&d);
   C<int, 1> *ci2c = f4c(&e);
+  C<int, 1> *ci3c = f4c(&g);
   int       *ip1 = f4c(&f);
 }