aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2019-12-11 18:40:55 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2019-12-11 18:40:55 +0000
commitc20f7e9971d35b89f17ee6a1bc8ab2462288adda (patch)
treeeb39bd0f839f4939287f6b18c8f54fcb813f932f
parentcc3b6728a21185a418f81bed6142fcdec565cd89 (diff)
downloadgcc-c20f7e9971d35b89f17ee6a1bc8ab2462288adda.zip
gcc-c20f7e9971d35b89f17ee6a1bc8ab2462288adda.tar.gz
gcc-c20f7e9971d35b89f17ee6a1bc8ab2462288adda.tar.bz2
PR c++/92878 - Parenthesized init of aggregates in new-expression.
Ville pointed out that our paren init of aggregates doesn't work for auto a = new A(1, 2, 3); and I think it should: A new-expression that creates an object of type T initializes that object as follows: ... -- Otherwise, the new-initializer is interpreted according to the initialization rules of [dcl.init] for direct-initialization. so I think it follows that we should perform dcl.init#17.6.2.2. This doesn't work with new[]; we have: error ("parenthesized initializer in array new"); * init.c (build_new_1): Handle parenthesized initialization of aggregates in new-expression. * g++.dg/cpp2a/paren-init20.C: New test. From-SVN: r279240
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/init.c18
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/paren-init20.C54
4 files changed, 80 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7051a42..5a2ba31 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2019-12-11 Marek Polacek <polacek@redhat.com>
+
+ PR c++/92878 - Parenthesized init of aggregates in new-expression.
+ * init.c (build_new_1): Handle parenthesized initialization of
+ aggregates in new-expression.
+
2019-12-11 Jason Merrill <jason@redhat.com>
PR c++/92105 - decltype(decltype) error cascade.
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index ecd0951..6f4c918 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3608,10 +3608,22 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
tree ie;
/* We are processing something like `new int (10)', which
- means allocate an int, and initialize it with 10. */
+ means allocate an int, and initialize it with 10.
- ie = build_x_compound_expr_from_vec (*init, "new initializer",
- complain);
+ In C++20, also handle `new A(1, 2)'. */
+ if (cxx_dialect >= cxx2a
+ && AGGREGATE_TYPE_P (type)
+ && (*init)->length () > 1)
+ {
+ ie = build_tree_list_vec (*init);
+ ie = build_constructor_from_list (init_list_type_node, ie);
+ CONSTRUCTOR_IS_DIRECT_INIT (ie) = true;
+ CONSTRUCTOR_IS_PAREN_INIT (ie) = true;
+ ie = digest_init (type, ie, complain);
+ }
+ else
+ ie = build_x_compound_expr_from_vec (*init, "new initializer",
+ complain);
init_expr = cp_build_modify_expr (input_location, init_expr,
INIT_EXPR, ie, complain);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0942db0..aac5a76 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-12-11 Marek Polacek <polacek@redhat.com>
+
+ PR c++/92878 - Parenthesized init of aggregates in new-expression.
+ * g++.dg/cpp2a/paren-init20.C: New test.
+
2019-12-11 Martin Sebor <msebor@redhat.com>
PR middle-end/79221
diff --git a/gcc/testsuite/g++.dg/cpp2a/paren-init20.C b/gcc/testsuite/g++.dg/cpp2a/paren-init20.C
new file mode 100644
index 0000000..05da760
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/paren-init20.C
@@ -0,0 +1,54 @@
+// PR c++/92878 - Parenthesized init of aggregates in new-expression.
+// { dg-do compile { target c++2a } }
+// Test new TYPE(...).
+
+int f ();
+
+struct A
+{
+ int a;
+ int b;
+};
+
+void
+fn_A ()
+{
+ int i = 0;
+ auto y = new A(1, 2);
+ auto x = new A(++i, ++i);
+ auto z = new A(1, { ++i });
+ auto u = new A(1, f());
+}
+
+struct B
+{
+ int a;
+ int b;
+ int c = 42;
+};
+
+void
+fn_B ()
+{
+ int i = 0;
+ auto y = new B(1, 2);
+ auto x = new B(++i, ++i);
+ auto z = new B(1, { ++i });
+ auto u = new B(1, f());
+}
+
+struct C
+{
+ int a;
+ int b = 10;
+};
+
+void
+fn_C ()
+{
+ int i = 0;
+ auto y = new C(1);
+ auto x = new C(++i);
+ auto z = new C({ ++i });
+ auto u = new C(f());
+}