Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -3223,6 +3223,8 @@ // can handle that case properly. def note_ovl_candidate_non_deduced_mismatch_qualified : Note< "candidate template ignored: could not match %q0 against %q1">; +def note_ovl_candidate_ambiguous_base_classes : Note< + "candidate template ignored: ambiguous base classes of %0 match %1">; // Note that we don't treat templates differently for this diagnostic. def note_ovl_candidate_arity : Note<"candidate " Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -6446,6 +6446,8 @@ /// \brief The arguments included an overloaded function name that could /// not be resolved to a suitable function. TDK_FailedOverloadResolution, + /// \brief Multiple base classes could have been successfully deduced. + TDK_AmbiguousBaseClasses, /// \brief Deduction failed; that's all we know. TDK_MiscellaneousDeductionFailure }; Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -594,6 +594,7 @@ break; } + case Sema::TDK_AmbiguousBaseClasses: case Sema::TDK_NonDeducedMismatch: { // FIXME: Should allocate from normal heap so that we can free this later. DFIArguments *Saved = new (Context) DFIArguments; @@ -648,6 +649,7 @@ case Sema::TDK_Underqualified: case Sema::TDK_DeducedMismatch: case Sema::TDK_NonDeducedMismatch: + case Sema::TDK_AmbiguousBaseClasses: // FIXME: Destroy the data? Data = nullptr; break; @@ -684,6 +686,7 @@ case Sema::TDK_DeducedMismatch: case Sema::TDK_NonDeducedMismatch: case Sema::TDK_FailedOverloadResolution: + case Sema::TDK_AmbiguousBaseClasses: return TemplateParameter(); case Sema::TDK_Incomplete: @@ -715,6 +718,7 @@ case Sema::TDK_Underqualified: case Sema::TDK_NonDeducedMismatch: case Sema::TDK_FailedOverloadResolution: + case Sema::TDK_AmbiguousBaseClasses: return nullptr; case Sema::TDK_DeducedMismatch: @@ -748,6 +752,7 @@ case Sema::TDK_Underqualified: case Sema::TDK_DeducedMismatch: case Sema::TDK_NonDeducedMismatch: + case Sema::TDK_AmbiguousBaseClasses: return &static_cast(Data)->FirstArg; // Unhandled @@ -775,6 +780,7 @@ case Sema::TDK_Underqualified: case Sema::TDK_DeducedMismatch: case Sema::TDK_NonDeducedMismatch: + case Sema::TDK_AmbiguousBaseClasses: return &static_cast(Data)->SecondArg; // Unhandled @@ -9582,6 +9588,13 @@ << FirstTA << SecondTA; return; } + + case Sema::TDK_AmbiguousBaseClasses: + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_ambiguous_base_classes) + << *DeductionFailure.getSecondArg() << *DeductionFailure.getFirstArg(); + return; + // TODO: diagnose these individually, then kill off // note_ovl_candidate_bad_deduction, which is uselessly vague. case Sema::TDK_MiscellaneousDeductionFailure: @@ -9843,6 +9856,7 @@ case Sema::TDK_SubstitutionFailure: case Sema::TDK_DeducedMismatch: case Sema::TDK_NonDeducedMismatch: + case Sema::TDK_AmbiguousBaseClasses: case Sema::TDK_MiscellaneousDeductionFailure: return 3; Index: lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- lib/Sema/SemaTemplateDeduction.cpp +++ lib/Sema/SemaTemplateDeduction.cpp @@ -1483,8 +1483,11 @@ if (BaseResult == Sema::TDK_Success) { // If we've already seen some success, then deduction fails due to // an ambiguity (temp.deduct.call p5). - if (Successful) - return Sema::TDK_MiscellaneousDeductionFailure; + if (Successful) { + Info.FirstArg = TemplateArgument(ParamIn); + Info.SecondArg = TemplateArgument(ArgIn); + return Sema::TDK_AmbiguousBaseClasses; + } Successful = true; std::swap(SuccessfulDeduced, Deduced); 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 @@ -166,7 +166,7 @@ template struct B {}; struct D : B<0>, B<1> {}; -template int callee(B); // expected-note{{failed template argument deduction}} +template int callee(B); // expected-note{{candidate template ignored: ambiguous base classes of 'PR28195::D' match 'B'}} int caller() { callee(D()); // expected-error{{no matching function}}