diff options
author | Marek Polacek <polacek@redhat.com> | 2019-12-11 18:40:55 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2019-12-11 18:40:55 +0000 |
commit | c20f7e9971d35b89f17ee6a1bc8ab2462288adda (patch) | |
tree | eb39bd0f839f4939287f6b18c8f54fcb813f932f | |
parent | cc3b6728a21185a418f81bed6142fcdec565cd89 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/init.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/paren-init20.C | 54 |
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()); +} |