]> git.ipfire.org Git - thirdparty/gcc.git/commit
libstdc++: Allow constant initialization of std::atomic of types with padding [PR123875]
authorTomasz Kamiński <tkaminsk@redhat.com>
Thu, 29 Jan 2026 17:14:47 +0000 (18:14 +0100)
committerTomasz Kamiński <tkaminsk@redhat.com>
Tue, 10 Feb 2026 10:51:03 +0000 (11:51 +0100)
commit6b550d69fe7cb62ea6e240ce7a4ba29ce33aa1b1
tree3ea8e4818badc06e8bdf33983f1c0c5533bf3067
parent0912dfcd1e901d7dc1ff5e10528eefe3f3ff7b22
libstdc++: Allow constant initialization of std::atomic of types with padding [PR123875]

Currently for the types T that contains padding bits, std::atomic<T>(T)
constructor was not usable at compile-time in C++14 or later modes. This
regression caused by use of __builtin_clear_padding introduced in
r13-2548-g157236dbd62164.

This leads to two regressions when switching from C++11 to C++14
standard (or switching from GCC-12 to later version for C++14 standard),
where for type X that contains padding
* constexpr std::atomic<X> cx(X(...)) becomes ill-formed,
* std::atomic<X> gx(X(...)) with static storage duration, switch from
  static to dynamic initialization.
The latter breakage is silent and may introduced very hard to localize
order of initialization issues.

This patch mitigates above issue by not invoking the __builtin_clear_padding,
during constant initialization (std::__is_constant_evaluated() is false).
This is considered to be safe, as:
* for objects with static storage duration, padding bits are already
  cleared by zero-initialization
* for constexpr objects with non-static storage duration, there is no
  API that would allow user to observe padding bits on const atomic objects

To elaborate on the second point, values of padding bits in atomic can
be observed by:
* The compare_exchange_weak/compare_exchange_strong operations are mutating,
  so cannot be invoked on const objects.
* As atomic<X> is not required to store actual object of type X,
  observing its object representation does (via bitcast, memcpy), does
  not provide values of object representation of X. Furthermore, the
  operations are defined only for trivially_copyable types, and atomic
  specializations meets above requirement only due to bug in libstdc++
  (see PR67572).

Note that above will no longer hold, and the solution will need to be
revisited during implementation of C++26 paper P3309R3: constexpr
atomic and atomic_ref (it will be possible to call compare_exchange
during constant evaluation).

PR libstdc++/123875

libstdc++-v3/ChangeLog:

* include/bits/atomic_base.h (__atomic_impl::__clear_padding):
Use if constexpr unconditionally.
(__atomic_float<_Fp>::__atomic_float(_Fp)): Skip __clear_padding
call for constant evaluation.
* include/std/atomic (atomic<_Tp>::atomic(_Tp)): Likewise.
* testsuite/29_atomics/atomic/cons/static_zero_padding.cc: New test.

Reviewed-by: Patrick Palka <ppalka@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>
libstdc++-v3/include/bits/atomic_base.h
libstdc++-v3/include/std/atomic
libstdc++-v3/testsuite/29_atomics/atomic/cons/static_zero_padding.cc [new file with mode: 0644]