https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117827
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- --- gcc/cp/init.cc.jj 2025-01-02 11:47:10.771493771 +0100 +++ gcc/cp/init.cc 2025-01-22 17:56:48.268704123 +0100 @@ -4530,6 +4530,7 @@ build_vec_init (tree base, tree maxindex tree obase = base; bool xvalue = false; bool errors = false; + bool clear_rval = false; location_t loc = (init ? cp_expr_loc_or_input_loc (init) : location_of (base)); @@ -4720,6 +4721,10 @@ build_vec_init (tree base, tree maxindex errors = true; TARGET_EXPR_CLEANUP (iterator_targ) = e; CLEANUP_EH_ONLY (iterator_targ) = true; + /* Signal that we want to clear rval near the end of the statement + expression so that the the build_vec_delete_1 cleanup does nothing + after the whole construction succeeded. */ + clear_rval = true; /* Since we push this cleanup before doing any initialization, cleanups for any temporaries in the initialization are naturally within our @@ -5096,7 +5101,23 @@ build_vec_init (tree base, tree maxindex /* The value of the array initialization is the array itself, RVAL is a pointer to the first element. */ - finish_stmt_expr_expr (rval, stmt_expr); + if (clear_rval) + { + /* If there is a build_vec_delete_1 cleanup on rval, make sure + to return the value of rval but clear the rval variable so that + the cleanup does nothing when reaching this. So, emit + ({ ... base = rval; rval = nullptr; base; }) */ + finish_expr_stmt (cp_build_modify_expr (input_location, base, + NOP_EXPR, rval, + tf_warning_or_error)); + finish_expr_stmt (cp_build_modify_expr (input_location, rval, + NOP_EXPR, + build_zero_cst (ptype), + tf_warning_or_error)); + finish_stmt_expr_expr (base, stmt_expr); + } + else + finish_stmt_expr_expr (rval, stmt_expr); stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt); fixes this for me, but totally untested so far.