On Wed, 11 Feb 2026, Tomasz Kaminski wrote:
>
>
> On Wed, Feb 11, 2026 at 7:34 AM Tomasz Kaminski <[email protected]> wrote:
>
>
> On Tue, Feb 10, 2026 at 10:55 PM Patrick Palka <[email protected]> wrote:
> Tested on x86_64-pc-linux-gnu with GLIBCXX_TESTSUITE_STDS=11,14,20,
> does this look OK for trunk and backports (after r16-7199 gets
> backported)? Also tested with Clang 21.
>
> -- >8 --
>
> After the front end change r16-7199 both GCC and Clang allow
> non-empty constexpr constructor bodies in C++11 as an extension,
> so we can unconditionally enable the __builtin_clear_padding logic
> in std::atomic's constructor.
>
> PR libstdc++/114865
>
> libstdc++-v3/ChangeLog:
>
> * include/std/atomic (atomic<_Tp>::atomic(_Tp))
> [C++11]: Enable __builtin_clear_padding logic.
> * testsuite/29_atomics/atomic/cons/static_zero_padding.cc
> [C++11]: Enable test verifying cleared padding bits for a
> std::atomic local variable.
> ---
> libstdc++-v3/include/std/atomic | 5 ++++-
> .../testsuite/29_atomics/atomic/cons/static_zero_padding.cc | 2 --
> 2 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/libstdc++-v3/include/std/atomic
> b/libstdc++-v3/include/std/atomic
> index 56dbe7bf5b95..306667e3c633 100644
> --- a/libstdc++-v3/include/std/atomic
> +++ b/libstdc++-v3/include/std/atomic
> @@ -247,14 +247,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> atomic& operator=(const atomic&) = delete;
> atomic& operator=(const atomic&) volatile = delete;
>
> +#pragma GCC diagnostic push
> +#pragma GCC diagnostic ignored "-Wc++14-extensions" // constexpr ctor
> body
> constexpr atomic(_Tp __i) noexcept : _M_i(__i)
> {
> -#if __cplusplus >= 201402L && __has_builtin(__builtin_clear_padding)
> +#if __has_builtin(__builtin_clear_padding)
> if _GLIBCXX17_CONSTEXPR
> (__atomic_impl::__maybe_has_padding<_Tp>())
>
> if (!std::__is_constant_evaluated())
> __builtin_clear_padding(std::__addressof(_M_i));
> #endif
> }
> +#pragma GCC diagnostic pop
>
> operator _Tp() const noexcept
> { return load(); }
> diff --git
> a/libstdc++-v3/testsuite/29_atomics/atomic/cons/static_zero_padding.cc
> b/libstdc++-v3/testsuite/29_atomics/atomic/cons/static_zero_padding.cc
> index 506513647c6c..e3594fb1c8ea 100644
> ---
> a/libstdc++-v3/testsuite/29_atomics/atomic/cons/static_zero_padding.cc
> +++
> b/libstdc++-v3/testsuite/29_atomics/atomic/cons/static_zero_padding.cc
> @@ -57,9 +57,7 @@ void test_struct(std::atomic<T>& g, const T& zp)
>
> std::atomic<T> l(T{1, 2});
> std::memcpy(&t, &zp, sizeof(T));
> -#if __cplusplus >= 201402L // Remove once PR114865 is fixed
> VERIFY( l.compare_exchange_strong(t, d) );
> -#endif
>
> Could you add here, and in functions below a test where atomic is allocated
> on heap. Recently stack variable got erroneous value, and sure how that
> impacts
> padding (test was failing for me), but we sure it will not be zeroed on heap.
>
> I.e. having something like:
> std::unique_ptr<std::atomic<T>> h(new atomic<T>(T{1, 2})); // make_unique is
> C++14
> std::memcpy(&t, &zp, sizeof(T));
> VERIFY( h->compare_exchange_strong(t, d) );
>
> And maybe rename the file to zero_padding.cc, i.e. remove static_.
Maybe it'd suffice to just run the original P0528 test in C++11 mode?
Can confirm it runs fine in c++11 mode after this patch.
-- >8 --
Subject: [PATCH] libstdc++: Clear padding bits in std::atomic ctor in C++11
[PR114865]
Tested on x86_64-pc-linux-gnu with GLIBCXX_TESTSUITE_STDS=11,14,20,
does this look OK for trunk and backports (after r16-7199 gets
backported)? Also tested with Clang 21.
-- >8 --
After the front end change r16-7199 both GCC and Clang allow non-empty
constexpr constructor bodies in C++11 as an extension, so we can now
unconditionally enable the __builtin_clear_padding logic in std::atomic's
constructor.
PR libstdc++/114865
libstdc++-v3/ChangeLog:
* include/std/atomic (atomic<_Tp>::atomic(_Tp)) [C++11]:
Enable __builtin_clear_padding logic.
* testsuite/29_atomics/atomic/compare_exchange_padding.cc: Change
target selector from c++20 to c++11.
* testsuite/29_atomics/atomic/cons/static_zero_padding.cc [C++11]:
Enable test verifying cleared padding bits for an std::atomic
local variable.
---
libstdc++-v3/include/std/atomic | 5 ++++-
.../testsuite/29_atomics/atomic/compare_exchange_padding.cc | 2 +-
.../testsuite/29_atomics/atomic/cons/static_zero_padding.cc | 2 --
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 56dbe7bf5b95..306667e3c633 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -247,14 +247,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
atomic& operator=(const atomic&) = delete;
atomic& operator=(const atomic&) volatile = delete;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++14-extensions" // constexpr ctor body
constexpr atomic(_Tp __i) noexcept : _M_i(__i)
{
-#if __cplusplus >= 201402L && __has_builtin(__builtin_clear_padding)
+#if __has_builtin(__builtin_clear_padding)
if _GLIBCXX17_CONSTEXPR (__atomic_impl::__maybe_has_padding<_Tp>())
if (!std::__is_constant_evaluated())
__builtin_clear_padding(std::__addressof(_M_i));
#endif
}
+#pragma GCC diagnostic pop
operator _Tp() const noexcept
{ return load(); }
diff --git
a/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
b/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
index a6081968ca86..d9c7b90c1a5c 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/compare_exchange_padding.cc
@@ -1,4 +1,4 @@
-// { dg-do run { target c++20 } }
+// { dg-do run { target c++11 } }
// { dg-require-atomic-cmpxchg-word "" }
// { dg-add-options libatomic }
// { dg-additional-options "-fno-tree-sra" }
diff --git
a/libstdc++-v3/testsuite/29_atomics/atomic/cons/static_zero_padding.cc
b/libstdc++-v3/testsuite/29_atomics/atomic/cons/static_zero_padding.cc
index 506513647c6c..e3594fb1c8ea 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic/cons/static_zero_padding.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/cons/static_zero_padding.cc
@@ -57,9 +57,7 @@ void test_struct(std::atomic<T>& g, const T& zp)
std::atomic<T> l(T{1, 2});
std::memcpy(&t, &zp, sizeof(T));
-#if __cplusplus >= 201402L // Remove once PR114865 is fixed
VERIFY( l.compare_exchange_strong(t, d) );
-#endif
constexpr std::atomic<T> cl(T{1, 2});
}
--
2.53.0.68.g864f55e190