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