Hello,

this patch fixes the issue reported at
http://stackoverflow.com/q/20860535/1918193

that the error we get when implicitly constructing from an initializer list using an explicit constructor doesn't have sfinae magic.

Bootstrap+testsuite on x86_64-unknown-linux-gnu.

2014-01-01  Marc Glisse  <marc.gli...@inria.fr>

gcc/cp/
        * call.c (convert_like_real): Check complain.
gcc/testsuite/
        * g++.dg/cpp0x/initlist-explicit-sfinae.C: New file.

--
Marc Glisse
Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c       (revision 206274)
+++ gcc/cp/call.c       (working copy)
@@ -5927,20 +5927,22 @@ convert_like_real (conversion *convs, tr
        tree convfn = cand->fn;
        unsigned i;
 
        /* When converting from an init list we consider explicit
           constructors, but actually trying to call one is an error.  */
        if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn)
            /* Unless this is for direct-list-initialization.  */
            && !(BRACE_ENCLOSED_INITIALIZER_P (expr)
                 && CONSTRUCTOR_IS_DIRECT_INIT (expr)))
          {
+           if (!(complain & tf_error))
+             return error_mark_node;
            error ("converting to %qT from initializer list would use "
                   "explicit constructor %qD", totype, convfn);
          }
 
        /* If we're initializing from {}, it's value-initialization.  */
        if (BRACE_ENCLOSED_INITIALIZER_P (expr)
            && CONSTRUCTOR_NELTS (expr) == 0
            && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype))
          {
            bool direct = CONSTRUCTOR_IS_DIRECT_INIT (expr);
Index: gcc/testsuite/g++.dg/cpp0x/initlist-explicit-sfinae.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/initlist-explicit-sfinae.C       (revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/initlist-explicit-sfinae.C       (working copy)
@@ -0,0 +1,47 @@
+// { dg-do compile }
+// { dg-options -std=c++11 }
+template<typename _Tp>
+_Tp&& declval() noexcept;
+
+template<bool b>
+struct bt {
+    static constexpr bool value = b;
+};
+
+template <typename To_, typename... From_>
+class my_is_convertible_many {
+  private:
+    template <typename To>
+      struct indirector {
+       indirector(To);
+      };
+
+    template <typename To, typename... From>
+      struct tag {};
+
+    template <typename To, typename... From>
+      static auto test(tag<To, From...>)
+      -> decltype(indirector<To>({declval<From>()...}), bt<true>());
+    static auto test(...)
+      -> bt<false>;
+
+  public:
+    static constexpr bool value = decltype(test(tag<To_, From_...>()))::value;
+};
+
+struct A {};
+struct B {};
+struct C {};
+
+struct Test {
+  Test(A, A);
+  //Test(B, B);
+  explicit Test(C, C);
+}; 
+
+int main() {    
+  static_assert(my_is_convertible_many<Test, A, A>::value,""); // true, correct
+  static_assert(!my_is_convertible_many<Test, B, B>::value,""); // false, 
correct
+  static_assert(!my_is_convertible_many<Test, C, C>::value,""); // error
+  return 0;
+}

Property changes on: gcc/testsuite/g++.dg/cpp0x/initlist-explicit-sfinae.C
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision URL
\ No newline at end of property

Reply via email to