https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71229

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The problem is that cxx_eval_store_expression first calls
          HOST_WIDE_INT i
            = find_array_ctor_elt (*valp, index, /*insert*/true);
which allocates a constructor_elt with filled index, but NULL_TREE value,
then we call
  init = cxx_eval_constant_expression (&new_ctx, init, false,
                                       non_constant_p, overflow_p);
which references the same ARRAY_REF as is on the lhs and thus ICE on the
NULL_TREE value from there, and then finally would store the actual value in
there.
It seems that for arrays of aggregates or vectors we already preinitialize
*valp if it is NULL_TREE before calling cxx_eval_constant_expression for init,
but for scalars we don't.
For the scalar case when !no_zero_init we could perhaps just do:
      tree val = build_value_init (elem_type, tf_warning_or_error);
      *valp = cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
                                           overflow_p);
or so before calling cxx_eval_constant_expression for init.  But not sure what
to do for the no_zero_init case, we want to diagnose it (rather than ICE), but
we don't know if cxx_eval_constant_expression will actually use it or not.
Another possibility is to handle NULL in constructor_elt's value specially (but
maybe in multiple cases) - if CONSTRUCTOR_NO_ZERO_INIT by issuing diagnostics,
otherwise value initializing it.
Or make sure to evaluate cxx_eval_constant_expression for init before resolving
the lhs during cxx_eval_store_expression.

Jason, any preferences (or do you want to take this over)?

Reply via email to