erik.pilkington created this revision. erik.pilkington added reviewers: rsmith, faisalv. erik.pilkington added a subscriber: cfe-commits.
Previously, clang would give a terrible diagnostic for the following: ``` template <int N> struct B {}; struct D : B<0>, B<1> {}; template <int N> int f(B<N>) { return 0; } // error, ambiguous bases of 'D' could be deduced. int main() { f(D()); } ``` This patch just introduces a new deduction failure kind: `TDK_AmbiguousBaseClasses`, and uses it to emit a better diagnostic. Thanks! http://reviews.llvm.org/D22311 Files: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplateDeduction.cpp test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp
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<int N> struct B {}; struct D : B<0>, B<1> {}; -template<int N> int callee(B<N>); // expected-note{{failed template argument deduction}} +template<int N> int callee(B<N>); // expected-note{{candidate template ignored: ambiguous base classes of 'PR28195::D' match 'B<N>'}} int caller() { callee(D()); // expected-error{{no matching function}} 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: 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<DFIArguments*>(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<DFIArguments*>(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: 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: 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 "
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits