https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126335
--- Comment #4 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The trunk branch has been updated by Marek Polacek <[email protected]>: https://gcc.gnu.org/g:e3da9acc2462e43e0ce3b9a5d414b988c35595c3 commit r17-2835-ge3da9acc2462e43e0ce3b9a5d414b988c35595c3 Author: Marek Polacek <[email protected]> Date: Thu Jul 30 15:18:14 2026 -0400 c++: fix array initialization wrong code [PR126335] This is a wrong-code problem starting with the recent check_initializer simplification (r17-1661). I thought the fix would be to bring some of those dropped conditions back, but now I think the change just uncovered a latent bug. Since r17-1661, when initializing 'm' of type 'M[2]' we no longer call build_aggr_init_full_exprs in check_initializer; instead, we go on to store_init_value -> split_nonconstant_init. There we arrive with: {{.a=TARGET_EXPR <D.3136, <<< Unknown tree: aggr_init_expr 3 operator""_s D.3136 >>>>, .b=TARGET_EXPR <D.3139, <<< Unknown tree: aggr_init_expr 3 operator""_s D.3139 >>>>}, {.a={.p=&empty.str}, .b={.p=&empty.str}}} which so far seems OK. The type is an array so split_nonconstant_init_1 delegates to build_vec_init and returns true which, as the comment says, should mean that "the whole of the value was initialized by the generated statements". This is inaccurate: since try_const and do_static_init are both true in build_vec_init, we have split out the constant initializer (the {.a={.p=&empty.str}, .b={.p=&empty.str}} part) into DECL_INITIAL: 5374 else if (do_static_init && !vec_safe_is_empty (const_vec)) 5375 DECL_INITIAL (obase) = build_constructor (atype, const_vec); so we have both dynamic and static initializers. But since split_nonconstant_init_1 returns bool, it's not ready to signal this case to split_nonconstant_init, which then does: 943 if (split_nonconstant_init_1 (dest, init, true, &flags)) 944 init = NULL_TREE; and then overwrites DECL_INITIAL (dest). So we've lost a half of the initializer and got wrong-code as the result. This patch fixes it by not throwing away the DECL_INITIAL that build_vec_init set for us. I suppose another approach would be to somehow change split_nonconstant_init_1/ARRAY_TYPE to follow the element pruning/add_stmt like the rest of the function, but that seems more complicated. PR c++/126335 gcc/cp/ChangeLog: * typeck2.cc (split_nonconstant_init): Assert that DECL_INITIAL is initially null. Don't clear DECL_INITIAL if build_vec_init set it. Only clear TREE_READONLY if CODE has side-effects. gcc/testsuite/ChangeLog: * g++.dg/init/array68.C: New test. Reviewed-by: Jason Merrill <[email protected]>
