[cfe-commits] r81898 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaInit.cpp lib/Sema/SemaOverload.cpp test/SemaCXX/deleted-function.cpp test/SemaCXX/direct-initializer.cpp

Fariborz Jahanian fjahanian at apple.com
Tue Sep 15 12:12:21 PDT 2009


Author: fjahanian
Date: Tue Sep 15 14:12:21 2009
New Revision: 81898

URL: http://llvm.org/viewvc/llvm-project?rev=81898&view=rev
Log:
Issue good diagnostics when initialization failes due to
ambiguity in type conversion function selection.


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

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

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Sep 15 14:12:21 2009
@@ -1643,6 +1643,8 @@
 // FIXME: %2 is an english string here.
 def err_typecheck_convert_incompatible : Error<
   "incompatible type %2 %1, expected %0">;
+def err_typecheck_convert_ambiguous : Error<
+  "ambiguity in initializing value of type %0 with initializer of type %1">;
 def err_cannot_initialize_decl_noname : Error<
   "cannot initialize a value of type %0 with an %select{rvalue|lvalue}1 "
   "of type %2">;

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Sep 15 14:12:21 2009
@@ -734,6 +734,15 @@
     return NULL;
   }
 
+  /// OverloadingResult - Capture the result of performing overload
+  /// resolution.
+  enum OverloadingResult {
+    OR_Success,             ///< Overload resolution succeeded.
+    OR_No_Viable_Function,  ///< No viable function found.
+    OR_Ambiguous,           ///< Ambiguous candidates found.
+    OR_Deleted              ///< Overload resoltuion refers to a deleted function.
+  };
+
 
   /// Subroutines of ActOnDeclarator().
   TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T);
@@ -770,7 +779,7 @@
   bool CheckMemberPointerConversion(Expr *From, QualType ToType,
                                     CastExpr::CastKind &Kind);
   bool IsQualificationConversion(QualType FromType, QualType ToType);
-  bool IsUserDefinedConversion(Expr *From, QualType ToType,
+  OverloadingResult IsUserDefinedConversion(Expr *From, QualType ToType,
                                UserDefinedConversionSequence& User,
                                OverloadCandidateSet& Conversions,
                                bool AllowConversionFunctions,
@@ -808,15 +817,6 @@
 
   bool PerformObjectMemberConversion(Expr *&From, NamedDecl *Member);
 
-  /// OverloadingResult - Capture the result of performing overload
-  /// resolution.
-  enum OverloadingResult {
-    OR_Success,             ///< Overload resolution succeeded.
-    OR_No_Viable_Function,  ///< No viable function found.
-    OR_Ambiguous,           ///< Ambiguous candidates found.
-    OR_Deleted              ///< Overload resoltuion refers to a deleted function.
-  };
-
   // Members have to be NamespaceDecl* or TranslationUnitDecl*.
   // TODO: make this is a typesafe union.
   typedef llvm::SmallPtrSet<DeclContext   *, 16> AssociatedNamespaceSet;

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Sep 15 14:12:21 2009
@@ -70,11 +70,23 @@
 
   if (S.getLangOptions().CPlusPlus) {
     // FIXME: I dislike this error message. A lot.
-    if (S.PerformImplicitConversion(Init, DeclType, "initializing", DirectInit))
-      return S.Diag(Init->getSourceRange().getBegin(),
-                    diag::err_typecheck_convert_incompatible)
-        << DeclType << Init->getType() << "initializing"
-        << Init->getSourceRange();
+    if (S.PerformImplicitConversion(Init, DeclType, 
+                                    "initializing", DirectInit)) {
+      ImplicitConversionSequence ICS;
+      OverloadCandidateSet CandidateSet;
+      if (S.IsUserDefinedConversion(Init, DeclType, ICS.UserDefined,
+                              CandidateSet,
+                              true, false, false) != S.OR_Ambiguous)
+        return S.Diag(Init->getSourceRange().getBegin(),
+                      diag::err_typecheck_convert_incompatible)
+                      << DeclType << Init->getType() << "initializing"
+                      << Init->getSourceRange();
+      S.Diag(Init->getSourceRange().getBegin(),
+             diag::err_typecheck_convert_ambiguous)
+            << DeclType << Init->getType() << Init->getSourceRange();
+      S.PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
+      return true;
+    }
     return false;
   }
 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Sep 15 14:12:21 2009
@@ -417,7 +417,7 @@
            IsUserDefinedConversion(From, ToType, ICS.UserDefined,
                                    Conversions,
                                    !SuppressUserConversions, AllowExplicit,
-                                   ForceRValue)) {
+                                   ForceRValue) == OR_Success) {
     ICS.ConversionKind = ImplicitConversionSequence::UserDefinedConversion;
     // C++ [over.ics.user]p4:
     //   A conversion of an expression of class type to the same class
@@ -1355,7 +1355,8 @@
 ///
 /// \param ForceRValue  true if the expression should be treated as an rvalue
 /// for overload resolution.
-bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
+Sema::OverloadingResult Sema::IsUserDefinedConversion(
+                                   Expr *From, QualType ToType,
                                    UserDefinedConversionSequence& User,
                                    OverloadCandidateSet& CandidateSet,
                                    bool AllowConversionFunctions,
@@ -1458,7 +1459,7 @@
         User.After.FromTypePtr
           = ThisType->getAs<PointerType>()->getPointeeType().getAsOpaquePtr();
         User.After.ToTypePtr = ToType.getAsOpaquePtr();
-        return true;
+        return OR_Success;
       } else if (CXXConversionDecl *Conversion
                    = dyn_cast<CXXConversionDecl>(Best->Function)) {
         // C++ [over.ics.user]p1:
@@ -1480,24 +1481,25 @@
         //   user-defined conversion sequence (see 13.3.3 and
         //   13.3.3.1).
         User.After = Best->FinalConversion;
-        return true;
+        return OR_Success;
       } else {
         assert(false && "Not a constructor or conversion function?");
-        return false;
+        return OR_No_Viable_Function;
       }
 
     case OR_No_Viable_Function:
+      return OR_No_Viable_Function;
     case OR_Deleted:
       // No conversion here! We're done.
-      return false;
+      return OR_Deleted;
 
     case OR_Ambiguous:
       // FIXME: See C++ [over.best.ics]p10 for the handling of
       // ambiguous conversion sequences.
-      return false;
+      return OR_Ambiguous;
     }
 
-  return false;
+  return OR_No_Viable_Function;
 }
 
 /// CompareImplicitConversionSequences - Compare two implicit
@@ -2100,10 +2102,9 @@
     return false;
 
     OverloadCandidateSet CandidateSet;
-    IsUserDefinedConversion(From, Context.BoolTy, ICS.UserDefined,
+    if (IsUserDefinedConversion(From, Context.BoolTy, ICS.UserDefined,
                             CandidateSet,
-                            true, true, false);
-    if (CandidateSet.begin() == CandidateSet.end())
+                            true, true, false) != OR_Ambiguous)
       return  Diag(From->getSourceRange().getBegin(),
                    diag::err_typecheck_bool_condition)
                     << From->getType() << From->getSourceRange();

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

==============================================================================
--- cfe/trunk/test/SemaCXX/deleted-function.cpp (original)
+++ cfe/trunk/test/SemaCXX/deleted-function.cpp Tue Sep 15 14:12:21 2009
@@ -18,7 +18,7 @@
 struct WithDel {
   WithDel() = delete; // expected-note {{candidate function has been explicitly deleted}}
   void fn() = delete; // expected-note {{function has been explicitly marked deleted here}}
-  operator int() = delete;
+  operator int() = delete; 
   void operator +(int) = delete;
 
   int i = delete; // expected-error {{only functions can have deleted definitions}}

Modified: cfe/trunk/test/SemaCXX/direct-initializer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/direct-initializer.cpp?rev=81898&r1=81897&r2=81898&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/direct-initializer.cpp (original)
+++ cfe/trunk/test/SemaCXX/direct-initializer.cpp Tue Sep 15 14:12:21 2009
@@ -34,3 +34,17 @@
 
   Z z; // expected-error{{no matching constructor for initialization of 'z'}}
 }
+
+struct Base {
+   operator int*() const; // expected-note {{candidate function}}
+};
+
+struct Derived : Base {
+   operator int*(); // expected-note {{candidate function}}
+};
+
+void foo(const Derived cd, Derived d) {
+        int *pi = cd;
+        int *ppi = d; // expected-error {{ambiguity in initializing value of type 'int *' with initializer of type 'struct Derived'}}
+
+}





More information about the cfe-commits mailing list