]> granicus.if.org Git - clang/commitdiff
TDK_InconsistentQuals is really totally different from TDK_Inconsistent.
authorJohn McCall <rjmccall@apple.com>
Thu, 5 Aug 2010 09:05:08 +0000 (09:05 +0000)
committerJohn McCall <rjmccall@apple.com>
Thu, 5 Aug 2010 09:05:08 +0000 (09:05 +0000)
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
lib/Sema/Sema.h
lib/Sema/SemaOverload.cpp
lib/Sema/SemaTemplateDeduction.cpp
test/SemaTemplate/deduction.cpp

index bebc333f6d1a0537f9fac3ca73736031f2a722f5..a917e2a74f30b4441702a7045256b20e5c1df8f9 100644 (file)
@@ -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">;
     
index 967d4757da4b60448d68ebed4a1f02ff25317052..b367608c7aa18a92807c63b9c57e4ae1f27c9b32 100644 (file)
@@ -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,
index 14761b6e5008e0c706cc84aa7f47815ec2acd280..037bc7b76b7e9917e8126d90cffce88199512265 100644 (file)
@@ -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))
index 3f54bbe43362927b969cc4ed6ac65f9169002d3b..e677b2666bb89e7e927f6f9f443e790143e46e08 100644 (file)
@@ -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");
index e8ff8d3a6d24fe6f31c4ae87defad5a3794464da..0dfb8d6b2cea97891bf81dd8a2b9e58531146f91 100644 (file)
@@ -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'}}
+  }
+}