From: Fariborz Jahanian Date: Tue, 22 Sep 2009 19:53:15 +0000 (+0000) Subject: Issue good ambiguity diagnostic when convesion fails. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=455acd9452f5b2a69d7ab8e53f733e46b500473a;p=clang Issue good ambiguity diagnostic when convesion fails. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82565 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 1ca9a1fb1b..a3d15fedc3 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1634,8 +1634,8 @@ def err_type_defined_in_condition : Error< "types may not be defined in conditions">; def err_typecheck_bool_condition : Error< "value of type %0 is not contextually convertible to 'bool'">; -def err_typecheck_ambiguous_bool_condition : Error< - "conversion from %0 to 'bool' is ambiguous">; +def err_typecheck_ambiguous_condition : Error< + "conversion from %0 to %1 is ambiguous">; def err_expected_class_or_namespace : Error<"expected a class or namespace">; def err_invalid_declarator_scope : Error< "definition or redeclaration of %0 not in a namespace enclosing %1">; diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 063b387fba..f7a5cb9b1b 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -1983,10 +1983,19 @@ bool Sema::PerformCopyInitialization(Expr *&From, QualType ToType, if (!PerformImplicitConversion(From, ToType, Flavor, /*AllowExplicit=*/false, Elidable)) return false; - - return Diag(From->getSourceRange().getBegin(), - diag::err_typecheck_convert_incompatible) - << ToType << From->getType() << Flavor << From->getSourceRange(); + ImplicitConversionSequence ICS; + OverloadCandidateSet CandidateSet; + if (IsUserDefinedConversion(From, ToType, ICS.UserDefined, + CandidateSet, + true, false, false) != OR_Ambiguous) + return Diag(From->getSourceRange().getBegin(), + diag::err_typecheck_convert_incompatible) + << ToType << From->getType() << Flavor << From->getSourceRange(); + Diag(From->getSourceRange().getBegin(), + diag::err_typecheck_ambiguous_condition) + << From->getType() << ToType << From->getSourceRange(); + PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false); + return true; } /// TryObjectArgumentInitialization - Try to initialize the object @@ -2104,13 +2113,13 @@ bool Sema::PerformContextuallyConvertToBool(Expr *&From) { OverloadCandidateSet CandidateSet; if (IsUserDefinedConversion(From, Context.BoolTy, ICS.UserDefined, CandidateSet, - true, true, false) != OR_Ambiguous) + true, false, false) != OR_Ambiguous) return Diag(From->getSourceRange().getBegin(), diag::err_typecheck_bool_condition) << From->getType() << From->getSourceRange(); Diag(From->getSourceRange().getBegin(), - diag::err_typecheck_ambiguous_bool_condition) - << From->getType() << From->getSourceRange(); + diag::err_typecheck_ambiguous_condition) + << From->getType() << Context.BoolTy << From->getSourceRange(); PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false); return true; } diff --git a/test/SemaCXX/ambig-user-defined-convesions.cpp b/test/SemaCXX/ambig-user-defined-convesions.cpp new file mode 100644 index 0000000000..d391a04d07 --- /dev/null +++ b/test/SemaCXX/ambig-user-defined-convesions.cpp @@ -0,0 +1,19 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +struct BASE { + operator int &(); // expected-note {{candidate function}} +}; +struct BASE1 { + operator int &(); // expected-note {{candidate function}} +}; + +struct B : public BASE, BASE1 { + +}; + +extern B f(); + +const int main() { + return f(); // expected-error {{conversion from 'struct B' to 'int const' is ambiguous}} +} +