Index: lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- lib/Sema/SemaTemplateDeduction.cpp +++ lib/Sema/SemaTemplateDeduction.cpp @@ -1421,21 +1421,29 @@ const TemplateSpecializationType *SpecParam = cast(Param); + SmallVector DeducedOrig(Deduced.begin(), + Deduced.end()); + // Try to deduce template arguments from the template-id. Sema::TemplateDeductionResult Result = DeduceTemplateArguments(S, TemplateParams, SpecParam, Arg, Info, Deduced); 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 - // class of the form template-id, A can be a pointer to a derived - // class pointed to by the deduced A. + // C++14 [temp.deduct.call] p4b3: + // If P is a class and P has the form simple-template-id, then the + // transformed A can be a derived class of the deduced A. Likewise if + // P is a pointer to a class of the form simple-template-id, the + // transformed A can be a pointer to a derived class pointed to by the + // deduced A. // - // More importantly: // These alternatives are considered only if type deduction would - // otherwise fail. + // otherwise fail. If they yield more than one possible deduced A, the + // type deduction fails. + + // Reset the incorrectly deduced argument from above. + Deduced = DeducedOrig; + if (const RecordType *RecordT = Arg->getAs()) { // We cannot inspect base classes as part of deduction when the type // is incomplete, so either instantiate any templates necessary to @@ -1450,8 +1458,6 @@ SmallVector ToVisit; ToVisit.push_back(RecordT); bool Successful = false; - SmallVector DeducedOrig(Deduced.begin(), - Deduced.end()); while (!ToVisit.empty()) { // Retrieve the next class in the inheritance hierarchy. const RecordType *NextT = ToVisit.pop_back_val(); Index: test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp =================================================================== --- test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp +++ test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp @@ -146,3 +146,17 @@ } } + +namespace PR27155 { + +struct B {}; + +template struct D : T {}; +template void Foo(D); + +int fn() { + D, 0> f; + Foo(f); +} + +}