https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121894
Jesus Martinez Cruz <jmcruz at uma dot es> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jmcruz at uma dot es
--- Comment #17 from Jesus Martinez Cruz <jmcruz at uma dot es> ---
The DSE part of comment #0 (a .DEFERRED_INIT that is partially overwritten
is not trimmed) still reproduces after r16-3956. Since -std=c++26 enables
this initialization by default (P2795 erroneous values), it now affects
ordinary C++26 code. A testcase with a constructor that writes the first
half of an inline buffer:
void use(const void*);
struct D {
char buf[1024];
D() { __builtin_memset(buf, 'x', 512); }
};
void test_d() { D d; use(&d); }
g++ -std=c++26 -O2 (also -O3), GCC 16.2 and trunk:
test_d():
memset(rsp, 0, 1024)
memset(rsp, 'x', 512)
call use
-fdump-tree-optimized:
d = .DEFERRED_INIT (1024, 4, &"d"[0]);
__builtin_memset (&d.buf, 120, 512);
use (&d);
Clang (-ftrivial-auto-var-init=zero -O2) trims the auto-init store to the
part that is not overwritten: memset(rsp+512, 0, 512).
This pattern (header initialized, inline buffer partially written) is
common in small-buffer types (std::string SSO, inplace_vector,
small_vector, fmt::memory_buffer). WG21 paper P4424R0 (B. Revzin,
"[[indeterminate]] for non-static data members") measures its cost with
GCC 16 in a large codebase: https://wg21.link/p4424r0
Compiler (gcc -v):
gcc version 17.0.0 20261025 (experimental), revision
cd7a85774a992c4759ebd03a26ce03cbb934e4d9 (Compiler Explorer gcc-snapshot)
Target: x86_64-linux-gnu
Command: g++ -std=c++26 -O2 -S test.cc
Compiler Explorer: https://godbolt.org/z/9xcGneasW