DR 1518 DR 1630 PR c++/54835 PR c++/60417
authorJason Merrill <jason@redhat.com>
Wed, 6 May 2015 02:07:34 +0000 (22:07 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 6 May 2015 02:07:34 +0000 (22:07 -0400)
DR 1518
DR 1630
PR c++/54835
PR c++/60417
* call.c (convert_like_real): Check value-initialization before
explicit.
* typeck2.c (process_init_constructor_record): Don't set
CONSTRUCTOR_IS_DIRECT_INIT.
(process_init_constructor_array): Likewise.
* init.c (build_vec_init): Likewise.

From-SVN: r222836

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/init.c
gcc/cp/typeck2.c
gcc/testsuite/g++.dg/cpp0x/initlist-dr1518.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/initlist40.C

index 17c2d1d9887936e7bde58aea4eafa0221487075b..3276b76bbb392d69e09a3d429fe7c8bb0d6317b9 100644 (file)
@@ -1,3 +1,16 @@
+2015-05-05  Jason Merrill  <jason@redhat.com>
+
+       DR 1518
+       DR 1630
+       PR c++/54835
+       PR c++/60417
+       * call.c (convert_like_real): Check value-initialization before
+       explicit.
+       * typeck2.c (process_init_constructor_record): Don't set
+       CONSTRUCTOR_IS_DIRECT_INIT.
+       (process_init_constructor_array): Likewise.
+       * init.c (build_vec_init): Likewise.
+
 2015-05-05  David Malcolm  <dmalcolm@redhat.com>
 
        * parser.c (cp_parser_asm_definition): Only test for
index 7bdf2365de6749502777ad2931dfc9cff0d4eeca..b77f69a267e1b0542c44effcbc52685215ef8213 100644 (file)
@@ -6243,19 +6243,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        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.  */
-           && !DIRECT_LIST_INIT_P (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 we're initializing from {}, it's value-initialization.  Note
+          that under the resolution of core 1630, value-initialization can
+          use explicit constructors.  */
        if (BRACE_ENCLOSED_INITIALIZER_P (expr)
            && CONSTRUCTOR_NELTS (expr) == 0
            && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype))
@@ -6271,6 +6261,18 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
            return expr;
          }
 
+       /* 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.  */
+           && !DIRECT_LIST_INIT_P (expr))
+         {
+           if (!(complain & tf_error))
+             return error_mark_node;
+           error ("converting to %qT from initializer list would use "
+                  "explicit constructor %qD", totype, convfn);
+         }
+
        expr = mark_rvalue_use (expr);
 
        /* Set user_conv_p on the argument conversions, so rvalue/base
index a4fc9ff33cdd7d09f4258e14eb5312e2f04fda34..c41e30cff5c807836efb2c486b292ddb3471d732 100644 (file)
@@ -3720,7 +3720,6 @@ build_vec_init (tree base, tree maxindex, tree init,
          if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type))
            {
              init = build_constructor (init_list_type_node, NULL);
-             CONSTRUCTOR_IS_DIRECT_INIT (init) = true;
            }
          else
            {
index c0df8237a1264692cc3f93703e89b6a33e9f0aca..6e0c777eac1fb95e163f71913104ec0c7c5af627 100644 (file)
@@ -1285,7 +1285,6 @@ process_init_constructor_array (tree type, tree init,
               we can't rely on the back end to do it for us, so make the
               initialization explicit by list-initializing from T{}.  */
            next = build_constructor (init_list_type_node, NULL);
-           CONSTRUCTOR_IS_DIRECT_INIT (next) = true;
            next = massage_init_elt (TREE_TYPE (type), next, complain);
            if (initializer_zerop (next))
              /* The default zero-initialization is fine for us; don't
@@ -1396,9 +1395,6 @@ process_init_constructor_record (tree type, tree init,
             for us, so build up TARGET_EXPRs.  If the type in question is
             a class, just build one up; if it's an array, recurse.  */
          next = build_constructor (init_list_type_node, NULL);
-         /* Call this direct-initialization pending DR 1518 resolution so
-            that explicit default ctors don't break valid C++03 code.  */
-         CONSTRUCTOR_IS_DIRECT_INIT (next) = true;
          next = massage_init_elt (TREE_TYPE (field), next, complain);
 
          /* Warn when some struct elements are implicitly initialized.  */
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-dr1518.C b/gcc/testsuite/g++.dg/cpp0x/initlist-dr1518.C
new file mode 100644 (file)
index 0000000..9f8ee0b
--- /dev/null
@@ -0,0 +1,27 @@
+// DR 1518
+// { dg-do compile { target c++11 } }
+
+struct A {
+  explicit A() = default;
+};
+
+struct B : A {
+  explicit B() = default;
+};
+
+struct C {
+  explicit C();
+};
+
+struct D : A {
+  C c;
+  explicit D() = default;
+};
+
+template<typename T> void f() {
+  T t = {};
+}
+template<typename T> void g() {
+  void x(T t);
+  x({});
+}
index 6e6a11a64541b1f5393365790e16a74719c5d028..de2e19d3adcf7e157ca8cc52b25f7971a58d01a6 100644 (file)
@@ -8,6 +8,6 @@ struct A
 
 int main()
 {
-  A a1 = { };                  // { dg-error "explicit" }
+  A a1 = { };
   A a2 = { 24 };               // { dg-error "explicit" }
 }