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.

Reply via email to