aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Beaumont-Gay <matthewbg@google.com>2012-11-08 20:50:02 +0000
committerMatt Beaumont-Gay <matthewbg@google.com>2012-11-08 20:50:02 +0000
commit45a37da030be06bb7babf5e65a64d62cd0def7e6 (patch)
treec133fffaa493ef15e18a6d366869fd6702a196f9
parentc4497036cff93da286ae188cfd95aa3f01390c61 (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.cpp14
-rw-r--r--test/SemaCXX/ambiguous-conversion-show-overload.cpp21
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}}