[cfe-commits] r151577 - in /cfe/trunk: include/clang/Sema/Overload.h lib/Sema/SemaOverload.cpp test/SemaCXX/cxx0x-initializer-constructor.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Mon Feb 27 14:38:27 PST 2012


Author: cornedbee
Date: Mon Feb 27 16:38:26 2012
New Revision: 151577

URL: http://llvm.org/viewvc/llvm-project?rev=151577&view=rev
Log:
Implement a FIXME for conversion sequence distinction. Should fix PR12092.

Modified:
    cfe/trunk/include/clang/Sema/Overload.h
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp

Modified: cfe/trunk/include/clang/Sema/Overload.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Overload.h?rev=151577&r1=151576&r2=151577&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Overload.h (original)
+++ cfe/trunk/include/clang/Sema/Overload.h Mon Feb 27 16:38:26 2012
@@ -401,11 +401,15 @@
     };
 
     /// ConversionKind - The kind of implicit conversion sequence.
-    unsigned ConversionKind : 31;
+    unsigned ConversionKind : 30;
 
     /// \brief Whether the argument is an initializer list.
     bool ListInitializationSequence : 1;
 
+    /// \brief Whether the target is really a std::initializer_list, and the
+    /// sequence only represents the worst element conversion.
+    bool StdInitializerListElement : 1;
+
     void setKind(Kind K) {
       destruct();
       ConversionKind = K;
@@ -435,13 +439,16 @@
     };
 
     ImplicitConversionSequence() 
-      : ConversionKind(Uninitialized), ListInitializationSequence(false) {}
+      : ConversionKind(Uninitialized), ListInitializationSequence(false),
+        StdInitializerListElement(false)
+    {}
     ~ImplicitConversionSequence() {
       destruct();
     }
     ImplicitConversionSequence(const ImplicitConversionSequence &Other)
       : ConversionKind(Other.ConversionKind), 
-        ListInitializationSequence(Other.ListInitializationSequence)
+        ListInitializationSequence(Other.ListInitializationSequence),
+        StdInitializerListElement(Other.StdInitializerListElement)
     {
       switch (ConversionKind) {
       case Uninitialized: break;
@@ -536,6 +543,16 @@
       ListInitializationSequence = true;
     }
 
+    /// \brief Whether the target is really a std::initializer_list, and the
+    /// sequence only represents the worst element conversion.
+    bool isStdInitializerListElement() const {
+      return StdInitializerListElement;
+    }
+
+    void setStdInitializerListElement(bool V = true) {
+      StdInitializerListElement = V;
+    }
+
     // The result of a comparison between implicit conversion
     // sequences. Use Sema::CompareImplicitConversionSequences to
     // actually perform the comparison.

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=151577&r1=151576&r2=151577&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Feb 27 16:38:26 2012
@@ -3163,9 +3163,15 @@
   // list-initialization sequence L2 if L1 converts to std::initializer_list<X>
   // for some X and L2 does not.
   if (Result == ImplicitConversionSequence::Indistinguishable &&
+      !ICS1.isBad() &&
       ICS1.isListInitializationSequence() &&
       ICS2.isListInitializationSequence()) {
-    // FIXME: Find out if ICS1 converts to initializer_list and ICS2 doesn't.
+    if (ICS1.isStdInitializerListElement() &&
+        !ICS2.isStdInitializerListElement())
+      return ImplicitConversionSequence::Better;
+    if (!ICS1.isStdInitializerListElement() &&
+        ICS2.isStdInitializerListElement())
+      return ImplicitConversionSequence::Worse;
   }
 
   return Result;
@@ -4241,11 +4247,12 @@
   //   all the elements can be implicitly converted to X, the implicit
   //   conversion sequence is the worst conversion necessary to convert an
   //   element of the list to X.
+  bool toStdInitializerList = false;
   QualType X;
   if (ToType->isArrayType())
     X = S.Context.getBaseElementType(ToType);
   else
-    (void)S.isStdInitializerList(ToType, &X);
+    toStdInitializerList = S.isStdInitializerList(ToType, &X);
   if (!X.isNull()) {
     for (unsigned i = 0, e = From->getNumInits(); i < e; ++i) {
       Expr *Init = From->getInit(i);
@@ -4265,6 +4272,7 @@
         Result = ICS;
     }
     Result.setListInitializationSequence();
+    Result.setStdInitializerListElement(toStdInitializerList);
     return Result;
   }
 

Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp?rev=151577&r1=151576&r2=151577&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp Mon Feb 27 16:38:26 2012
@@ -194,3 +194,21 @@
     H h4 = {1, 1}; // expected-error {{no matching constructor}}
   };
 }
+
+namespace PR12092 {
+
+  struct S {
+    S(const char*);
+  };
+  struct V {
+    template<typename T> V(T, T);
+    void f(std::initializer_list<S>);
+    void f(const V &);
+  };
+
+  void g() {
+    extern V s;
+    s.f({"foo", "bar"});
+  }
+
+}





More information about the cfe-commits mailing list