]> granicus.if.org Git - clang/commitdiff
Don't produce duplicate notes if we have deduction failure notes when resolving
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 14 Aug 2013 00:00:44 +0000 (00:00 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 14 Aug 2013 00:00:44 +0000 (00:00 +0000)
the address of an overloaded function template.

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

lib/Sema/SemaOverload.cpp
test/CXX/over/over.over/p2.cpp
test/SemaCXX/addr-of-overloaded-function-casting.cpp
test/SemaCXX/cxx1y-deduced-return-type.cpp
test/SemaObjCXX/arc-nsconsumed-errors.mm

index c77abe8155bce0ff6dd03de5bf1996ad6d6a92c2..06d1f0b0e2d4fd1693bb60a0f0fa348410967d2a 100644 (file)
@@ -9390,7 +9390,6 @@ private:
       FailedCandidates.addCandidate()
           .set(FunctionTemplate->getTemplatedDecl(),
                MakeDeductionFailureInfo(Context, Result, Info));
-      (void)Result;
       return false;
     } 
     
@@ -9531,10 +9530,22 @@ public:
     S.Diag(OvlExpr->getLocStart(), diag::err_addr_ovl_no_viable)
         << OvlExpr->getName() << TargetFunctionType
         << OvlExpr->getSourceRange();
-    FailedCandidates.NoteCandidates(S, OvlExpr->getLocStart());
-    S.NoteAllOverloadCandidates(OvlExpr, TargetFunctionType);
-  } 
-  
+    if (FailedCandidates.empty())
+      S.NoteAllOverloadCandidates(OvlExpr, TargetFunctionType);
+    else {
+      // We have some deduction failure messages. Use them to diagnose
+      // the function templates, and diagnose the non-template candidates
+      // normally.
+      for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
+                                 IEnd = OvlExpr->decls_end();
+           I != IEnd; ++I)
+        if (FunctionDecl *Fun =
+                dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()))
+          S.NoteOverloadCandidate(Fun, TargetFunctionType);
+      FailedCandidates.NoteCandidates(S, OvlExpr->getLocStart());
+    }
+  }
+
   bool IsInvalidFormOfPointerToMemberFunction() const {
     return TargetTypeIsNonStaticMemberFunction &&
       !OvlExprInfo.HasFormOfMemberPointer;
@@ -9695,7 +9706,6 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
       FailedCandidates.addCandidate()
           .set(FunctionTemplate->getTemplatedDecl(),
                MakeDeductionFailureInfo(Context, Result, Info));
-      (void)Result;
       continue;
     }
 
index b6c1d6bfa25bd00afb76042ea2dedc3cd9abdce6..d03b84a2d15b1d19c48c1b2b9af6a1e9c3420cdd 100644 (file)
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
 template <typename T>
-T f0(T, T); // expected-note{{candidate}} expected-note{{candidate function}}
+T f0(T, T); // expected-note{{deduced conflicting types for parameter 'T' ('int' vs. 'float')}}
 
 void test_f0() {
   int (*f0a)(int, int) = f0;
index 8698736b3aebf711dda5b97a89c3f018a3c0bfc5..784c8a0007445da1d125b02d5ec2fc144d756987 100644 (file)
@@ -5,10 +5,10 @@ void f(); // expected-note 9{{candidate function}}
 void f(int); // expected-note 9{{candidate function}}
 
 template <class T>
-void t(T); // expected-note 6{{candidate function}} \
+void t(T); // expected-note 3{{candidate function}} \
            // expected-note 3{{candidate template ignored: could not match 'void' against 'int'}}
 template <class T>
-void t(T *); // expected-note 6{{candidate function}} \
+void t(T *); // expected-note 3{{candidate function}} \
              // expected-note 3{{candidate template ignored: could not match 'void' against 'int'}}
 
 template<class T> void u(T);
index 743ef4fbf2bc665f871c139640682f179514178e..b8cb5f86320e3db44c1fd760787cf27876064ded 100644 (file)
@@ -159,8 +159,7 @@ namespace Templates {
   double &mem_check4 = take_fn<double>(Outer<double>::arg_multi);
 
   namespace Deduce1 {
-  template <typename T> auto f() { return 0; } // expected-note {{candidate}} \
-                                               // expected-note {{candidate function has different return type ('int' expected but has 'auto')}}
+  template <typename T> auto f() { return 0; } // expected-note {{couldn't infer template argument 'T'}}
     template<typename T> void g(T(*)()); // expected-note 2{{candidate}}
     void h() {
       auto p = f<int>;
@@ -173,8 +172,7 @@ namespace Templates {
   }
 
   namespace Deduce2 {
-  template <typename T> auto f(int) { return 0; } // expected-note {{candidate}} \
-    // expected-note {{candidate function has different return type ('int' expected but has 'auto')}}
+  template <typename T> auto f(int) { return 0; } // expected-note {{couldn't infer template argument 'T'}}
     template<typename T> void g(T(*)(int)); // expected-note 2{{candidate}}
     void h() {
       auto p = f<int>;
index c1ce81b66938346cd0a09a8e73f2f558bee5cb7d..c78d8a5f4add4dc4241cff8713f998f5727c0329 100644 (file)
@@ -29,8 +29,7 @@ void releaser(__attribute__((ns_consumed)) id);
 releaser_t r2 = releaser; // no-warning
 
 template <typename T>
-void templateFunction(T) { } // expected-note {{candidate function}} \
-                             // expected-note {{candidate template ignored: could not match 'void (__strong id)' against 'void (id)'}} \
+void templateFunction(T) { } // expected-note {{candidate template ignored: could not match 'void (__strong id)' against 'void (id)'}} \
                              // expected-note {{candidate template ignored: failed template argument deduction}}
 releaser_t r3 = templateFunction<id>; // expected-error {{address of overloaded function 'templateFunction' does not match required type 'void (id)'}}