This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++] sfinae implicit-explicit construction


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.glisse@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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]