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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits