From 57e97786433e70197a089360228d8f0d82e3ad4c Mon Sep 17 00:00:00 2001 From: John McCall Date: Thu, 5 Aug 2010 09:05:08 +0000 Subject: [PATCH] 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 --- include/clang/Basic/DiagnosticSemaKinds.td | 3 ++ lib/Sema/Sema.h | 2 +- lib/Sema/SemaOverload.cpp | 39 +++++++++++++++++----- lib/Sema/SemaTemplateDeduction.cpp | 4 +-- test/SemaTemplate/deduction.cpp | 8 +++++ 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(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(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(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(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(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(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 void g (T_&); // expected-note{{T_ = int}} void h (void) { g(f()); } // expected-error{{no matching function for call}} } + +namespace test0 { + template 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'}} + } +} -- 2.40.0