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.