From: Richard Smith Date: Wed, 14 Aug 2013 00:00:44 +0000 (+0000) Subject: Don't produce duplicate notes if we have deduction failure notes when resolving X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=72a36a14b10c18bc72bf0472dc29e86327615c26;p=clang Don't produce duplicate notes if we have deduction failure notes when resolving the address of an overloaded function template. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188334 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index c77abe8155..06d1f0b0e2 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -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((*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; } diff --git a/test/CXX/over/over.over/p2.cpp b/test/CXX/over/over.over/p2.cpp index b6c1d6bfa2..d03b84a2d1 100644 --- a/test/CXX/over/over.over/p2.cpp +++ b/test/CXX/over/over.over/p2.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s template -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; diff --git a/test/SemaCXX/addr-of-overloaded-function-casting.cpp b/test/SemaCXX/addr-of-overloaded-function-casting.cpp index 8698736b3a..784c8a0007 100644 --- a/test/SemaCXX/addr-of-overloaded-function-casting.cpp +++ b/test/SemaCXX/addr-of-overloaded-function-casting.cpp @@ -5,10 +5,10 @@ void f(); // expected-note 9{{candidate function}} void f(int); // expected-note 9{{candidate function}} template -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 -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 void u(T); diff --git a/test/SemaCXX/cxx1y-deduced-return-type.cpp b/test/SemaCXX/cxx1y-deduced-return-type.cpp index 743ef4fbf2..b8cb5f8632 100644 --- a/test/SemaCXX/cxx1y-deduced-return-type.cpp +++ b/test/SemaCXX/cxx1y-deduced-return-type.cpp @@ -159,8 +159,7 @@ namespace Templates { double &mem_check4 = take_fn(Outer::arg_multi); namespace Deduce1 { - template auto f() { return 0; } // expected-note {{candidate}} \ - // expected-note {{candidate function has different return type ('int' expected but has 'auto')}} + template auto f() { return 0; } // expected-note {{couldn't infer template argument 'T'}} template void g(T(*)()); // expected-note 2{{candidate}} void h() { auto p = f; @@ -173,8 +172,7 @@ namespace Templates { } namespace Deduce2 { - template auto f(int) { return 0; } // expected-note {{candidate}} \ - // expected-note {{candidate function has different return type ('int' expected but has 'auto')}} + template auto f(int) { return 0; } // expected-note {{couldn't infer template argument 'T'}} template void g(T(*)(int)); // expected-note 2{{candidate}} void h() { auto p = f; diff --git a/test/SemaObjCXX/arc-nsconsumed-errors.mm b/test/SemaObjCXX/arc-nsconsumed-errors.mm index c1ce81b669..c78d8a5f4a 100644 --- a/test/SemaObjCXX/arc-nsconsumed-errors.mm +++ b/test/SemaObjCXX/arc-nsconsumed-errors.mm @@ -29,8 +29,7 @@ void releaser(__attribute__((ns_consumed)) id); releaser_t r2 = releaser; // no-warning template -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; // expected-error {{address of overloaded function 'templateFunction' does not match required type 'void (id)'}}