public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-8066] c++: constexpr non-trivial aggregate init [PR105191]
@ 2022-04-09 3:27 Jason Merrill
0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2022-04-09 3:27 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:4822108e61ab879067482704f2f7d1670813d61a
commit r12-8066-g4822108e61ab879067482704f2f7d1670813d61a
Author: Jason Merrill <jason@redhat.com>
Date: Fri Apr 8 15:33:41 2022 -0400
c++: constexpr non-trivial aggregate init [PR105191]
My patch for PR92385 made us use VEC_INIT_EXPR for aggregate initialization
of an array where some elements are not explicitly initialized. Constexpr
handling of that was treating initialization from {} as equivalent to
value-initialization, which is problematic for classes with default member
initializers that make the default constructor non-trivial; in older
standard modes, not initializing all members makes a constructor
non-constexpr, but aggregate initialization is fine.
PR c++/105191
PR c++/92385
gcc/cp/ChangeLog:
* tree.cc (build_vec_init_elt): Do {}-init for aggregates.
* constexpr.cc (cxx_eval_vec_init): Only treat {} as value-init
for non-aggregate types.
(build_vec_init_expr): Also check constancy of explicit
initializer elements.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/constexpr-array28.C: New test.
Diff:
---
gcc/cp/constexpr.cc | 3 ++-
gcc/cp/tree.cc | 27 +++++++++++++++++++++-----
gcc/testsuite/g++.dg/cpp0x/constexpr-array28.C | 21 ++++++++++++++++++++
3 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 9c40b051574..db78b4a6545 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -5008,7 +5008,8 @@ cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
bool value_init = VEC_INIT_EXPR_VALUE_INIT (t);
if (!init || !BRACE_ENCLOSED_INITIALIZER_P (init))
;
- else if (CONSTRUCTOR_NELTS (init) == 0)
+ else if (CONSTRUCTOR_NELTS (init) == 0
+ && !CP_AGGREGATE_TYPE_P (strip_array_types (atype)))
{
/* Handle {} as value-init. */
init = NULL_TREE;
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index 780a8d89165..63164bee638 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -740,7 +740,7 @@ build_cplus_new (tree type, tree init, tsubst_flags_t complain)
constructor calls until gimplification time; now we only do it to set
VEC_INIT_EXPR_IS_CONSTEXPR.
- We assume that init is either NULL_TREE, void_type_node (indicating
+ We assume that init is either NULL_TREE, {}, void_type_node (indicating
value-initialization), or another array to copy. */
static tree
@@ -752,7 +752,20 @@ build_vec_init_elt (tree type, tree init, tsubst_flags_t complain)
|| !CLASS_TYPE_P (inner_type))
/* No interesting initialization to do. */
return integer_zero_node;
- else if (init == void_type_node)
+ if (init && BRACE_ENCLOSED_INITIALIZER_P (init))
+ {
+ /* Even if init has initializers for some array elements,
+ we're interested in the {}-init of trailing elements. */
+ if (CP_AGGREGATE_TYPE_P (inner_type))
+ {
+ tree empty = build_constructor (init_list_type_node, nullptr);
+ return digest_init (inner_type, empty, complain);
+ }
+ else
+ /* It's equivalent to value-init. */
+ init = void_type_node;
+ }
+ if (init == void_type_node)
return build_value_init (inner_type, complain);
releasing_vec argvec;
@@ -808,9 +821,13 @@ build_vec_init_expr (tree type, tree init, tsubst_flags_t complain)
TREE_SIDE_EFFECTS (init) = true;
SET_EXPR_LOCATION (init, input_location);
- if (cxx_dialect >= cxx11
- && potential_constant_expression (elt_init))
- VEC_INIT_EXPR_IS_CONSTEXPR (init) = true;
+ if (cxx_dialect >= cxx11)
+ {
+ bool cx = potential_constant_expression (elt_init);
+ if (BRACE_ENCLOSED_INITIALIZER_P (init))
+ cx &= potential_constant_expression (init);
+ VEC_INIT_EXPR_IS_CONSTEXPR (init) = cx;
+ }
VEC_INIT_EXPR_VALUE_INIT (init) = value_init;
return init;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array28.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-array28.C
new file mode 100644
index 00000000000..d7706b9f0b4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-array28.C
@@ -0,0 +1,21 @@
+// PR c++/105191
+// { dg-do compile { target c++11 } }
+
+struct A {
+ const char* message = "";
+};
+
+enum class B { };
+
+struct C {
+ A a;
+ B b;
+};
+
+struct D {
+ C cs[1];
+};
+
+constexpr D ds[4] = {
+ D{},
+};
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-04-09 3:27 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-09 3:27 [gcc r12-8066] c++: constexpr non-trivial aggregate init [PR105191] Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).