On 10/1/25 7:10 AM, Jakub Jelinek wrote:
On Wed, Oct 01, 2025 at 12:14:02AM +0100, Jason Merrill wrote:kind of dummy loops which don't do anything for quite a lot of passes. And finally jump threading comes and because one function contains e.g. 4 or more of these one after another in the test ( void test_strcpy_new_char_array (size_t n) { size_t r_0_1 = UR (0, 1);T (S (0), new char[r_0_1][1]); T (S (1), new char[r_0_1][1]); // { dg-warning "\\\[-Wstringop-overflow" } T (S (1), new char[r_0_1][2]); T (S (2), new char[r_0_1][2]); // { dg-warning "\\\[-Wstringop-overflow" } } still reproduces it), it threads it by making separate paths for the r_0_1 == 0 and r_0_1 == 1 and guess the false positive is then on dead code or something. 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 sizesI did that in an earlier patch; it conflicted with an LWG issue resolution, but people seemed open to fixing that, so I could do it again.I see https://eel.is/c++draft/specialized.construct#3 has now return ::new (voidify(*location)) T[1](); for arrays, so adds an extra [1] extent, but I'm afraid I still don't understand the problem. Is that if the whole constant size array clobber is added for placement new only, or all new expressions? For heap allocations at constexpr time, I thought the type to the artificial VAR_DECL is assigned on casts, not on later clobbers.
The problem is that in e.g. cpp2a/constexpr-new23.C we end up trying to clobber an int[1] variable arr as int[1][1], and constexpr complains. Except that currently it doesn't because we don't emit the clobber before initializing a non-class, but it does if we change the int[1] to an array of class type.
In any case, if the whole array clobber is
something desirable for middle-end and undesirable for constexpr evaluation,
one option would be to guard it with if consteval { vec_init of elt_clobber }
else {
while_array_clobber } or so, or have both of those in the IL and just add some
magic flag (or temporary CLOBBER type) which would make constexpr evaluation
ignore the whole array clobber and throw away VEC_INIT_EXPR containing only
a CLOBBER in the body at genericization time (with the idea that we know
the middle-end will not find it useful).
That sounds fine.
Plus if possible add another set of clobbers right before the individual elt_type constructors within its loop (not sure how to arrange for that).
That should be reasonable, it was just easier to do as a separate loop. Maybe by adding a parm to build_vec_init or generalizing explicit_value_init_p.
What testcase breaks with the added whole array clobber if the VEC_INIT is not removed?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.Unfortunately we still need the clobber for constexpr placement new; with that change, if I modify constexpr-new4.C to take the new array bound as a parameter, it breaks.I can certainly try this one. Jakub
