From 23bafad985291c0563cf2cb291f0d0747553fcde Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Wed, 7 Nov 2012 21:17:13 +0000 Subject: [PATCH] When template deduction fails on a derived class, try a template deduction on 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. llvm-svn: 167550 --- clang/lib/Sema/SemaTemplateDeduction.cpp | 7 ++++++- clang/test/SemaTemplate/derived.cpp | 12 ++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 clang/test/SemaTemplate/derived.cpp diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 98e22c0..bf4533d 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -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/clang/test/SemaTemplate/derived.cpp b/clang/test/SemaTemplate/derived.cpp new file mode 100644 index 0000000..1fb9401 --- /dev/null +++ b/clang/test/SemaTemplate/derived.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template class vector2 {}; +template class vector : vector2 {}; + +template void Foo2(vector2 V) {} // expected-note{{candidate template ignored: can't deduce a type for 'T' which would make 'const T' equal 'int'}} +template void Foo(vector V) {} // expected-note {{candidate template ignored: can't deduce a type for 'T' which would make 'const T' equal 'int'}} + +void test() { + Foo2(vector2()); // expected-error{{no matching function for call to 'Foo2'}} + Foo(vector()); // expected-error{{no matching function for call to 'Foo'}} +} -- 2.7.4