On 4/4/20 1:56 PM, Marek Polacek wrote:
On Fri, Apr 03, 2020 at 10:39:49PM -0400, Jason Merrill via Gcc-patches wrote:
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?
It's because we set LOOKUP_ALREADY_DIGESTED a few lines below:
6813 /* Don't call digest_init; it's unnecessary and will
complain
6814 about aggregate initialization of non-aggregate
classes. */
6815 flags |= LOOKUP_ALREADY_DIGESTED;
and so store_init_value doesn't digest. Given the comment I'd be nervous about
not setting that flag here.
OK, then why isn't it called by build_aggr_init? How is the CONSTRUCTOR
getting a type without this being fixed up?
...
Ah, because build_vec_init builds up a new CONSTRUCTOR and gives it a
type without setting the indexes like process_init_constructor_array does:
Jason
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 27623cf4db1..ea95a3bc910 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -4438,6 +4438,8 @@ build_vec_init (tree base, tree maxindex, tree init,
errors = true;
if (try_const)
{
+ if (!field)
+ field = size_int (idx);
tree e = maybe_constant_init (one_init);
if (reduced_constant_expression_p (e))
{