diff options
author | Matt Beaumont-Gay <matthewbg@google.com> | 2012-11-08 20:50:02 +0000 |
---|---|---|
committer | Matt Beaumont-Gay <matthewbg@google.com> | 2012-11-08 20:50:02 +0000 |
commit | 45a37da030be06bb7babf5e65a64d62cd0def7e6 (patch) | |
tree | c133fffaa493ef15e18a6d366869fd6702a196f9 | |
parent | c4497036cff93da286ae188cfd95aa3f01390c61 (diff) |
Fix a bug I found while preparing my devmtg talk: When passing NULL to a
function that takes a const Foo&, where Foo is convertible from a large number
of pointer types, we print ALL the overloads, no matter the setting of
-fshow-overloads.
There is potential follow-on work in unifying the "print candidates, but not
too many" logic between OverloadCandidateSet::NoteCandidates and
ImplicitConversionSequence::DiagnoseAmbiguousConversion.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167596 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 14 | ||||
-rw-r--r-- | test/SemaCXX/ambiguous-conversion-show-overload.cpp | 21 |
2 files changed, 33 insertions, 2 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 8e8580d701..bf2b89741a 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -7992,10 +7992,20 @@ void ImplicitConversionSequence::DiagnoseAmbiguousConversion( const PartialDiagnostic &PDiag) const { S.Diag(CaretLoc, PDiag) << Ambiguous.getFromType() << Ambiguous.getToType(); - for (AmbiguousConversionSequence::const_iterator - I = Ambiguous.begin(), E = Ambiguous.end(); I != E; ++I) { + // FIXME: The note limiting machinery is borrowed from + // OverloadCandidateSet::NoteCandidates; there's an opportunity for + // refactoring here. + const OverloadsShown ShowOverloads = S.Diags.getShowOverloads(); + unsigned CandsShown = 0; + AmbiguousConversionSequence::const_iterator I, E; + for (I = Ambiguous.begin(), E = Ambiguous.end(); I != E; ++I) { + if (CandsShown >= 4 && ShowOverloads == Ovl_Best) + break; + ++CandsShown; S.NoteOverloadCandidate(*I); } + if (I != E) + S.Diag(SourceLocation(), diag::note_ovl_too_many_candidates) << int(E - I); } namespace { diff --git a/test/SemaCXX/ambiguous-conversion-show-overload.cpp b/test/SemaCXX/ambiguous-conversion-show-overload.cpp new file mode 100644 index 0000000000..64296512ff --- /dev/null +++ b/test/SemaCXX/ambiguous-conversion-show-overload.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -fshow-overloads=best -fno-caret-diagnostics %s 2>&1 | FileCheck %s +struct S { + S(void*); + S(char*); + S(unsigned char*); + S(signed char*); + S(unsigned short*); + S(signed short*); + S(unsigned int*); + S(signed int*); +}; +void f(const S& s); +void g() { + f(0); +} +// CHECK: {{conversion from 'int' to 'const S' is ambiguous}} +// CHECK-NEXT: {{candidate constructor}} +// CHECK-NEXT: {{candidate constructor}} +// CHECK-NEXT: {{candidate constructor}} +// CHECK-NEXT: {{candidate constructor}} +// CHECK-NEXT: {{remaining 4 candidates omitted; pass -fshow-overloads=all to show them}} |