On Mon, Sep 29, 2025 at 04:29:00PM +0200, Jakub Jelinek wrote:
> Anyway, on the C++ FE side I'd really recommend (but can be done
> incrementally of course) to emit one larger clobber for all the whole array
> if it has constant sizes and not emit clobbers at least for now at all if
> there is trivial constructor for the elements and we'd emit the clobbers in
> a loop.

Looking at the r16-3022 PR121068 commit, it looks like it was intentional
that way, but when the middle-end just ignores it, apparently not just for
the case of trivial initialization, but also non-trivial, I think it needs
to be reconsidered.  Using e.g. the following testcase, I see
even when using S::S () ctors, the clobbers are in a separate loop from the
ctor calls.

struct S { S (); ~S (); char s; };

auto
foo ()
{
  return new char[42][2];
}

auto
bar (int n)
{
  return new char[n][2];
}

auto
baz ()
{
  return new S[42][2];
}

auto
qux (int n)
{
  return new S[n][2];
}

auto
corge ()
{
  return new char[42];
}

auto
freddy (int n)
{
  return new char[n];
}

auto
garply ()
{
  return new S[42];
}

auto
boo (int n)
{
  return new S[n];
}

So, wonder if for the constant size initialization
we couldn't do something like (on top of your patch)
and for the non-constant array_p case perhaps instead arrange
for clobbers emitted in the same loop that initializes the elements.

--- gcc/cp/init.cc.jj   2025-09-30 16:35:49.720891711 +0200
+++ gcc/cp/init.cc      2025-09-30 19:25:55.078330853 +0200
@@ -3662,21 +3662,40 @@ build_new_1 (vec<tree, va_gc> **placemen
   tree clobber_expr = NULL_TREE;
   if (do_clobber)
     {
-      tree clobber = build_clobber (elt_type, CLOBBER_OBJECT_BEGIN);
-      CONSTRUCTOR_IS_DIRECT_INIT (clobber) = true;
       if (array_p)
        {
-         /* Clobber each element rather than the array at once.  */
          tree maxindex = cp_build_binary_op (input_location,
                                              MINUS_EXPR, outer_nelts,
-                                             integer_one_node,
-                                             complain);
-         clobber_expr = build_vec_init (data_addr, maxindex, clobber,
-                                        /*valinit*/false, /*from_arr*/0,
-                                        complain, nullptr);
+                                             integer_one_node, complain);
+         tree maxindex_cst = maybe_constant_value (maxindex);
+         if (TREE_CODE (maxindex_cst) == INTEGER_CST
+             && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (data_addr))))
+                 == INTEGER_CST))
+           {
+             tree etype = TREE_TYPE (TREE_TYPE (data_addr));
+             maxindex = fold_convert (sizetype, maxindex_cst);
+             tree atype
+               = build_array_type (etype, build_index_type (maxindex));
+             tree clobber = build_clobber (atype, CLOBBER_OBJECT_BEGIN);
+             tree targ = fold_convert (build_pointer_type (atype), data_addr);
+             targ = cp_build_fold_indirect_ref (targ);
+             /* Clobber the whole array at once.  */
+             clobber_expr = cp_build_init_expr (targ, clobber);
+           }
+         else
+           {
+             tree clobber = build_clobber (elt_type, CLOBBER_OBJECT_BEGIN);
+             CONSTRUCTOR_IS_DIRECT_INIT (clobber) = true;
+             /* Clobber each element rather than the array at once.  */
+             clobber_expr = build_vec_init (data_addr, maxindex, clobber,
+                                            /*valinit*/false, /*from_arr*/0,
+                                            complain, nullptr);
+           }
        }
       else
        {
+         tree clobber = build_clobber (elt_type, CLOBBER_OBJECT_BEGIN);
+         CONSTRUCTOR_IS_DIRECT_INIT (clobber) = true;
          tree targ = cp_build_fold_indirect_ref (data_addr);
          clobber_expr = cp_build_init_expr (targ, clobber);
        }


        Jakub

Reply via email to