On 4/3/20 9:08 PM, Marek Polacek wrote:
On Fri, Apr 03, 2020 at 03:01:37PM -0400, Jason Merrill via Gcc-patches wrote:
On 3/30/20 4:28 PM, Marek Polacek wrote:
Here we crash in the gimplifier because gimplify_init_ctor_eval doesn't
expect null indexes for a constructor:
/* ??? Here's to hoping the front end fills in all of the indices,
so we don't have to figure out what's missing ourselves. */
gcc_assert (purpose);
The indexes weren't filled because we never called reshape_init: for
a constructor that represents parenthesized initialization of an
aggregate we don't allow brace elision or designated initializers. So
fill in the indexes manually, here we have an array, and we can simply
assign indexes starting from 0.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
Shouldn't digest_init fill in the indexes? In
process_init_constructor_array I see
if (!ce->index)
ce->index = size_int (i);
Yes, that works too. Thus:
Bootstrapped/regtested on x86_64-linux, ok for trunk?
-- >8 --
Here we crash in the gimplifier because gimplify_init_ctor_eval doesn't
expect null indexes for a constructor:
/* ??? Here's to hoping the front end fills in all of the indices,
so we don't have to figure out what's missing ourselves. */
gcc_assert (purpose);
The indexes weren't filled because we never called reshape_init: for
a constructor that represents parenthesized initialization of an
aggregate we don't allow brace elision or designated initializers. So
call digest_init to fill in the indexes.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
PR c++/94155 - crash in gimplifier with paren init of aggregates.
* decl.c (check_initializer): Call digest_init.
* g++.dg/cpp2a/paren-init22.C: New test.
---
gcc/cp/decl.c | 5 +++++
gcc/testsuite/g++.dg/cpp2a/paren-init22.C | 15 +++++++++++++++
2 files changed, 20 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/cpp2a/paren-init22.C
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 69a238997b4..63e7bda09f5 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -6754,6 +6754,11 @@ check_initializer (tree decl, tree init, int flags,
vec<tree, va_gc> **cleanups)
init = build_constructor_from_list (init_list_type_node, init);
CONSTRUCTOR_IS_DIRECT_INIT (init) = true;
CONSTRUCTOR_IS_PAREN_INIT (init) = true;
+ /* The gimplifier expects that the front end fills in all of the
+ indices. Normally, reshape_init_array fills these in, but we
+ don't call reshape_init because that does nothing when it gets
+ CONSTRUCTOR_IS_PAREN_INIT. */
+ init = digest_init (type, init, tf_warning_or_error);
But why weren't we already calling digest_init in store_init_value? Was
the CONSTRUCTOR making it all the way to gimplification still having
init_list_type_node?
}
}
else if (TREE_CODE (init) == TREE_LIST
diff --git a/gcc/testsuite/g++.dg/cpp2a/paren-init22.C
b/gcc/testsuite/g++.dg/cpp2a/paren-init22.C
new file mode 100644
index 00000000000..1b2959e7731
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/paren-init22.C
@@ -0,0 +1,15 @@
+// PR c++/94155 - crash in gimplifier with paren init of aggregates.
+// { dg-do compile { target c++2a } }
+
+struct S { int i, j; };
+
+struct A {
+ S s;
+ constexpr A(S e) : s(e) {}
+};
+
+void
+f()
+{
+ A g[1]({{1, 1}});
+}
base-commit: 0c809f727cd2a6c70c307d9dd53d26dc84bf292a