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

Reply via email to