summaryrefslogtreecommitdiff
path: root/gcc/cp/tree.c
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2019-12-03 15:59:40 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2019-12-03 15:59:40 +0000
commit43aae289866f5ea55d187444520412554aa2e171 (patch)
treea3a517242014a3db820710f763749398c1d1e0f0 /gcc/cp/tree.c
parent577f4a0e5e7f7ef9b5729a3eed79e523cba9dfa9 (diff)
downloadgcc-43aae289866f5ea55d187444520412554aa2e171.tar.gz
PR c++/91363 - P0960R3: Parenthesized initialization of aggregates.
This patch implements C++20 P0960R3: Parenthesized initialization of aggregates (<wg21.link/p0960>; see R0 for more background info). Essentially, if you have an aggregate, you can now initialize it by (x, y), similarly to {x, y}. E.g. struct A { int x, y; // no A(int, int) ctor (see paren-init14.C for = delete; case) }; A a(1, 2); The difference between ()-init and {}-init is that narrowing conversions are permitted, designators are not permitted, a temporary object bound to a reference does not have its lifetime extended, and there is no brace elision. Further, things like int a[](1, 2, 3); // will deduce the array size const A& r(1, 2.3, 3); // narrowing is OK int (&&rr)[](1, 2, 3); int b[3](1, 2); // b[2] will be value-initialized now work as expected. Note that char f[]("fluff"); has always worked and this patch keeps it that way. Also note that A a((1, 2)) is not the same as A a{{1,2}}; the inner (1, 2) remains a COMPOUND_EXPR. The approach I took was to handle (1, 2) similarly to {1, 2} -- conjure up a CONSTRUCTOR, and introduce LOOKUP_AGGREGATE_PAREN_INIT to distinguish between the two. This kind of initialization is only supported in C++20; I've made no attempt to support it in earlier standards, like we don't support CTAD pre-C++17, for instance. * c-cppbuiltin.c (c_cpp_builtins): Predefine __cpp_aggregate_paren_init=201902 for -std=c++2a. * call.c (build_new_method_call_1): Handle parenthesized initialization of aggregates by building up a CONSTRUCTOR. (extend_ref_init_temps): Do nothing for CONSTRUCTOR_IS_PAREN_INIT. * cp-tree.h (CONSTRUCTOR_IS_PAREN_INIT, LOOKUP_AGGREGATE_PAREN_INIT): Define. * decl.c (grok_reference_init): Handle aggregate initialization from a parenthesized list of values. (reshape_init): Do nothing for CONSTRUCTOR_IS_PAREN_INIT. (check_initializer): Handle initialization of an array from a parenthesized list of values. Use NULL_TREE instead of NULL. * tree.c (build_cplus_new): Handle BRACE_ENCLOSED_INITIALIZER_P. * typeck2.c (digest_init_r): Set LOOKUP_AGGREGATE_PAREN_INIT if it receives a CONSTRUCTOR with CONSTRUCTOR_IS_PAREN_INIT set. Allow narrowing when LOOKUP_AGGREGATE_PAREN_INIT. (massage_init_elt): Don't lose LOOKUP_AGGREGATE_PAREN_INIT when passing flags to digest_init_r. * g++.dg/cpp0x/constexpr-99.C: Only expect an error in C++17 and lesser. * g++.dg/cpp0x/explicit7.C: Likewise. * g++.dg/cpp0x/initlist12.C: Adjust dg-error. * g++.dg/cpp0x/pr31437.C: Likewise. * g++.dg/cpp2a/feat-cxx2a.C: Add __cpp_aggregate_paren_init test. * g++.dg/cpp2a/paren-init1.C: New test. * g++.dg/cpp2a/paren-init10.C: New test. * g++.dg/cpp2a/paren-init11.C: New test. * g++.dg/cpp2a/paren-init12.C: New test. * g++.dg/cpp2a/paren-init13.C: New test. * g++.dg/cpp2a/paren-init14.C: New test. * g++.dg/cpp2a/paren-init15.C: New test. * g++.dg/cpp2a/paren-init16.C: New test. * g++.dg/cpp2a/paren-init17.C: New test. * g++.dg/cpp2a/paren-init18.C: New test. * g++.dg/cpp2a/paren-init19.C: New test. * g++.dg/cpp2a/paren-init2.C: New test. * g++.dg/cpp2a/paren-init3.C: New test. * g++.dg/cpp2a/paren-init4.C: New test. * g++.dg/cpp2a/paren-init5.C: New test. * g++.dg/cpp2a/paren-init6.C: New test. * g++.dg/cpp2a/paren-init7.C: New test. * g++.dg/cpp2a/paren-init8.C: New test. * g++.dg/cpp2a/paren-init9.C: New test. * g++.dg/ext/desig10.C: Adjust dg-error. * g++.dg/template/crash107.C: Likewise. * g++.dg/template/crash95.C: Likewise. * g++.old-deja/g++.jason/crash3.C: Likewise. * g++.old-deja/g++.law/ctors11.C: Likewise. * g++.old-deja/g++.law/ctors9.C: Likewise. * g++.old-deja/g++.mike/net22.C: Likewise. * g++.old-deja/g++.niklas/t128.C: Likewise. From-SVN: r278939
Diffstat (limited to 'gcc/cp/tree.c')
-rw-r--r--gcc/cp/tree.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 8817860b4d3..8b625e8b18e 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -669,6 +669,15 @@ build_aggr_init_expr (tree type, tree init)
tree
build_cplus_new (tree type, tree init, tsubst_flags_t complain)
{
+ /* This function should cope with what build_special_member_call
+ can produce. When performing parenthesized aggregate initialization,
+ it can produce a { }. */
+ if (BRACE_ENCLOSED_INITIALIZER_P (init))
+ {
+ gcc_assert (cxx_dialect >= cxx2a);
+ return finish_compound_literal (type, init, complain);
+ }
+
tree rval = build_aggr_init_expr (type, init);
tree slot;