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)?