aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-08-05 09:05:08 +0000
committerJohn McCall <rjmccall@apple.com>2010-08-05 09:05:08 +0000
commit57e97786433e70197a089360228d8f0d82e3ad4c (patch)
treec1b4935e0103c3ae93ec16724b6119346a00770b
parentf5072afdfd5c2a45fd2adf3659b0696bc8c57717 (diff)
TDK_InconsistentQuals is really totally different from TDK_Inconsistent.
Rename it to TDK_Underqualified to avoid this sort of confusion and give it its own diagnostic. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110318 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--lib/Sema/Sema.h2
-rw-r--r--lib/Sema/SemaOverload.cpp39
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp4
-rw-r--r--test/SemaTemplate/deduction.cpp8
5 files changed, 45 insertions, 11 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index bebc333f6d..a917e2a74f 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1151,6 +1151,9 @@ def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note<
def note_ovl_candidate_instantiation_depth : Note<
"candidate template ignored: substitution exceeded maximum template "
"instantiation depth">;
+def note_ovl_candidate_underqualified : Note<
+ "candidate template ignored: can't deduce a type for %0 which would "
+ "make %2 equal %1">;
def note_ovl_candidate_substitution_failure : Note<
"candidate template ignored: substitution failure %0">;
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 967d4757da..b367608c7a 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -3320,7 +3320,7 @@ public:
/// cv-qualifiers on a template parameter type that would
/// otherwise be deduced, e.g., we tried to deduce T in "const T"
/// but were given a non-const "X".
- TDK_InconsistentQuals,
+ TDK_Underqualified,
/// \brief Substitution of the deduced template argument values
/// resulted in an error.
TDK_SubstitutionFailure,
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 14761b6e50..037bc7b76b 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -315,7 +315,7 @@ static MakeDeductionFailureInfo(ASTContext &Context,
break;
case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals: {
+ case Sema::TDK_Underqualified: {
// FIXME: Should allocate from normal heap so that we can free this later.
DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments;
Saved->Param = Info.Param;
@@ -348,7 +348,7 @@ void OverloadCandidate::DeductionFailureInfo::Destroy() {
break;
case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals:
+ case Sema::TDK_Underqualified:
// FIXME: Destroy the data?
Data = 0;
break;
@@ -380,7 +380,7 @@ OverloadCandidate::DeductionFailureInfo::getTemplateParameter() {
return TemplateParameter::getFromOpaqueValue(Data);
case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals:
+ case Sema::TDK_Underqualified:
return static_cast<DFIParamWithArguments*>(Data)->Param;
// Unhandled
@@ -402,7 +402,7 @@ OverloadCandidate::DeductionFailureInfo::getTemplateArgumentList() {
case Sema::TDK_Incomplete:
case Sema::TDK_InvalidExplicitArguments:
case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals:
+ case Sema::TDK_Underqualified:
return 0;
case Sema::TDK_SubstitutionFailure:
@@ -429,7 +429,7 @@ const TemplateArgument *OverloadCandidate::DeductionFailureInfo::getFirstArg() {
return 0;
case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals:
+ case Sema::TDK_Underqualified:
return &static_cast<DFIParamWithArguments*>(Data)->FirstArg;
// Unhandled
@@ -454,7 +454,7 @@ OverloadCandidate::DeductionFailureInfo::getSecondArg() {
return 0;
case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals:
+ case Sema::TDK_Underqualified:
return &static_cast<DFIParamWithArguments*>(Data)->SecondArg;
// Unhandled
@@ -5592,8 +5592,31 @@ void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand,
return;
}
- case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals: {
+ case Sema::TDK_Underqualified: {
+ assert(ParamD && "no parameter found for bad qualifiers deduction result");
+ TemplateTypeParmDecl *TParam = cast<TemplateTypeParmDecl>(ParamD);
+
+ QualType Param = Cand->DeductionFailure.getFirstArg()->getAsType();
+
+ // Param will have been canonicalized, but it should just be a
+ // qualified version of ParamD, so move the qualifiers to that.
+ QualifierCollector Qs(S.Context);
+ Qs.strip(Param);
+ QualType NonCanonParam = Qs.apply(TParam->getTypeForDecl());
+ assert(S.Context.hasSameType(Param, NonCanonParam));
+
+ // Arg has also been canonicalized, but there's nothing we can do
+ // about that. It also doesn't matter as much, because it won't
+ // have any template parameters in it (because deduction isn't
+ // done on dependent types).
+ QualType Arg = Cand->DeductionFailure.getSecondArg()->getAsType();
+
+ S.Diag(Fn->getLocation(), diag::note_ovl_candidate_underqualified)
+ << ParamD->getDeclName() << Arg << NonCanonParam;
+ return;
+ }
+
+ case Sema::TDK_Inconsistent: {
assert(ParamD && "no parameter found for inconsistent deduction result");
int which = 0;
if (isa<TemplateTypeParmDecl>(ParamD))
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 3f54bbe433..e677b2666b 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -428,9 +428,9 @@ DeduceTemplateArguments(Sema &S,
// type.
if (Param.isMoreQualifiedThan(Arg) && !(TDF & TDF_IgnoreQualifiers)) {
Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
- Info.FirstArg = Deduced[Index];
+ Info.FirstArg = TemplateArgument(Param);
Info.SecondArg = TemplateArgument(Arg);
- return Sema::TDK_InconsistentQuals;
+ return Sema::TDK_Underqualified;
}
assert(TemplateTypeParm->getDepth() == 0 && "Can't deduce with depth > 0");
diff --git a/test/SemaTemplate/deduction.cpp b/test/SemaTemplate/deduction.cpp
index e8ff8d3a6d..0dfb8d6b2c 100644
--- a/test/SemaTemplate/deduction.cpp
+++ b/test/SemaTemplate/deduction.cpp
@@ -105,3 +105,11 @@ namespace PR7463 {
template <typename T_> void g (T_&); // expected-note{{T_ = int}}
void h (void) { g(f()); } // expected-error{{no matching function for call}}
}
+
+namespace test0 {
+ template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: can't deduce a type for 'T' which would make 'T const' equal 'char'}}
+ char *char_maker();
+ void test() {
+ make(char_maker); // expected-error {{no matching function for call to 'make'}}
+ }
+}