]> granicus.if.org Git - clang/commitdiff
Record template argument deduction failures for member function
authorDouglas Gregor <dgregor@apple.com>
Sat, 8 May 2010 20:18:54 +0000 (20:18 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sat, 8 May 2010 20:18:54 +0000 (20:18 +0000)
templates and conversion function templates.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103349 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaOverload.cpp
test/SemaTemplate/overload-candidates.cpp

index b86719e15b97bf973eb64c4a9b06c945bf0668b0..517574b5955d45fafb239fc0dfb505f0ae0540ee 100644 (file)
@@ -288,7 +288,8 @@ namespace {
 /// \brief Convert from Sema's representation of template deduction information
 /// to the form used in overload-candidate information.
 OverloadCandidate::DeductionFailureInfo
-static MakeDeductionFailureInfo(Sema::TemplateDeductionResult TDK,
+static MakeDeductionFailureInfo(ASTContext &Context,
+                                Sema::TemplateDeductionResult TDK,
                                 Sema::TemplateDeductionInfo &Info) {
   OverloadCandidate::DeductionFailureInfo Result;
   Result.Result = static_cast<unsigned>(TDK);
@@ -307,7 +308,8 @@ static MakeDeductionFailureInfo(Sema::TemplateDeductionResult TDK,
       
   case Sema::TDK_Inconsistent:
   case Sema::TDK_InconsistentQuals: {
-    DFIParamWithArguments *Saved = new DFIParamWithArguments;
+    // FIXME: Should allocate from normal heap so that we can free this later.
+    DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments;
     Saved->Param = Info.Param;
     Saved->FirstArg = Info.FirstArg;
     Saved->SecondArg = Info.SecondArg;
@@ -3249,11 +3251,18 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
   if (TemplateDeductionResult Result
       = DeduceTemplateArguments(MethodTmpl, ExplicitTemplateArgs,
                                 Args, NumArgs, Specialization, Info)) {
-        // FIXME: Record what happened with template argument deduction, so
-        // that we can give the user a beautiful diagnostic.
-        (void)Result;
-        return;
-      }
+    CandidateSet.push_back(OverloadCandidate());
+    OverloadCandidate &Candidate = CandidateSet.back();
+    Candidate.FoundDecl = FoundDecl;
+    Candidate.Function = MethodTmpl->getTemplatedDecl();
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_bad_deduction;
+    Candidate.IsSurrogate = false;
+    Candidate.IgnoreObjectArgument = false;
+    Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, 
+                                                          Info);
+    return;
+  }
 
   // Add the function template specialization produced by template argument
   // deduction as a candidate.
@@ -3300,7 +3309,8 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
     Candidate.FailureKind = ovl_fail_bad_deduction;
     Candidate.IsSurrogate = false;
     Candidate.IgnoreObjectArgument = false;
-    Candidate.DeductionFailure = MakeDeductionFailureInfo(Result, Info);
+    Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, 
+                                                          Info);
     return;
   }
 
@@ -3447,9 +3457,16 @@ Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
   if (TemplateDeductionResult Result
         = DeduceTemplateArguments(FunctionTemplate, ToType,
                                   Specialization, Info)) {
-    // FIXME: Record what happened with template argument deduction, so
-    // that we can give the user a beautiful diagnostic.
-    (void)Result;
+    CandidateSet.push_back(OverloadCandidate());
+    OverloadCandidate &Candidate = CandidateSet.back();
+    Candidate.FoundDecl = FoundDecl;
+    Candidate.Function = FunctionTemplate->getTemplatedDecl();
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_bad_deduction;
+    Candidate.IsSurrogate = false;
+    Candidate.IgnoreObjectArgument = false;
+    Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, 
+                                                          Info);
     return;
   }
 
index 937d633e68b09f498dcc0246bd745792a8cda3af..8762cc80630a52ea4b819a94d7b7f3e39123d9eb 100644 (file)
@@ -29,3 +29,12 @@ template<typename T>
 void test_get_type(int *ptr) {
   (void)get_type(ptr); // expected-error{{no matching function for call to 'get_type'}}
 }
+
+struct X {
+  template<typename T>
+  const T& min(const T&, const T&); // expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'long')}}
+};
+
+void test_X_min(X x) {
+  (void)x.min(1, 2l); // expected-error{{no matching member function for call to 'min'}}
+}