[cfe-commits] r81812 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaOverload.cpp test/SemaCXX/conversion-function.cpp

Fariborz Jahanian fjahanian at apple.com
Mon Sep 14 17:10:11 PDT 2009


Author: fjahanian
Date: Mon Sep 14 19:10:11 2009
New Revision: 81812

URL: http://llvm.org/viewvc/llvm-project?rev=81812&view=rev
Log:
Issue a good diagnostics when attempt to select
a type convesion function results in ambiguity.


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/conversion-function.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=81812&r1=81811&r2=81812&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Sep 14 19:10:11 2009
@@ -1619,6 +1619,8 @@
   "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_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">;

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=81812&r1=81811&r2=81812&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Sep 14 19:10:11 2009
@@ -772,6 +772,7 @@
   bool IsQualificationConversion(QualType FromType, QualType ToType);
   bool IsUserDefinedConversion(Expr *From, QualType ToType,
                                UserDefinedConversionSequence& User,
+                               OverloadCandidateSet& Conversions,
                                bool AllowConversionFunctions,
                                bool AllowExplicit, bool ForceRValue);
 

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=81812&r1=81811&r2=81812&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Sep 14 19:10:11 2009
@@ -410,10 +410,12 @@
                             bool AllowExplicit, bool ForceRValue,
                             bool InOverloadResolution) {
   ImplicitConversionSequence ICS;
+  OverloadCandidateSet Conversions;
   if (IsStandardConversion(From, ToType, InOverloadResolution, ICS.Standard))
     ICS.ConversionKind = ImplicitConversionSequence::StandardConversion;
   else if (getLangOptions().CPlusPlus &&
            IsUserDefinedConversion(From, ToType, ICS.UserDefined,
+                                   Conversions,
                                    !SuppressUserConversions, AllowExplicit,
                                    ForceRValue)) {
     ICS.ConversionKind = ImplicitConversionSequence::UserDefinedConversion;
@@ -1355,9 +1357,9 @@
 /// for overload resolution.
 bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
                                    UserDefinedConversionSequence& User,
+                                   OverloadCandidateSet& CandidateSet,
                                    bool AllowConversionFunctions,
                                    bool AllowExplicit, bool ForceRValue) {
-  OverloadCandidateSet CandidateSet;
   if (const RecordType *ToRecordType = ToType->getAs<RecordType>()) {
     if (CXXRecordDecl *ToRecordDecl
           = dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) {
@@ -2097,9 +2099,19 @@
   if (!PerformImplicitConversion(From, Context.BoolTy, ICS, "converting"))
     return false;
 
-  return Diag(From->getSourceRange().getBegin(),
-              diag::err_typecheck_bool_condition)
-    << From->getType() << From->getSourceRange();
+    OverloadCandidateSet CandidateSet;
+    IsUserDefinedConversion(From, Context.BoolTy, ICS.UserDefined,
+                            CandidateSet,
+                            true, true, false);
+    if (CandidateSet.begin() == CandidateSet.end())
+      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();
+    PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
+    return true;
 }
 
 /// AddOverloadCandidate - Adds the given function to the set of

Modified: cfe/trunk/test/SemaCXX/conversion-function.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conversion-function.cpp?rev=81812&r1=81811&r2=81812&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/conversion-function.cpp (original)
+++ cfe/trunk/test/SemaCXX/conversion-function.cpp Mon Sep 14 19:10:11 2009
@@ -79,16 +79,16 @@
 // Test. Conversion in base class is visible in derived class.
 class XB { 
 public:
-  operator int();
+  operator int(); // expected-note {{candidate function}}
 };
 
 class Yb : public XB { 
 public:
-  operator char();
+  operator char(); // expected-note {{candidate function}}
 };
 
 void f(Yb& a) {
-  if (a) { } // expected-error {{value of type 'class Yb' is not contextually convertible to 'bool'}}
+  if (a) { } // expected-error {{conversion from 'class Yb' to 'bool' is ambiguous}}
   int i = a; // OK. calls XB::operator int();
   char ch = a;  // OK. calls Yb::operator char();
 }





More information about the cfe-commits mailing list