Hi, I found __atomic_float constructor does not clear padding,
while __compare_exchange assumes it as zeroed padding. So it is easy to
reproducing a infinite loop in X86-64 with long double type like:
---
-O0 -std=c++23 -mlong-double-80
#include <stdio.h>
#include <atomic>

#define T long double
int main() {
    std::atomic<T> t(0.5);
    t.fetch_add(0.5);
    float x = t;
    printf("%f\n", x);
}
---

So we should add __builtin_clear_padding in __atomic_float constructor,
just like the generic atomic struct.

regtested on x86_64-linux. Is it OK for trunk?

---
libstdc++: atomic: Add missing clear_padding in __atomic_float constructor.

libstdc++-v3/ChangeLog:

* include/bits/atomic_base.h: add __builtin_clear_padding in __atomic_float
constructor.
---
 libstdc++-v3/include/bits/atomic_base.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/atomic_base.h
b/libstdc++-v3/include/bits/atomic_base.h
index f4ce0fa53..d59c2209e 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -1283,7 +1283,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION

       constexpr
       __atomic_float(_Fp __t) : _M_fp(__t)
-      { }
+      {
+#if __has_builtin(__builtin_clear_padding)
+ if _GLIBCXX17_CONSTEXPR (__atomic_impl::__maybe_has_padding<_Fp>())
+  __builtin_clear_padding(std::__addressof(_M_fp));
+#endif
+      }

       __atomic_float(const __atomic_float&) = delete;
       __atomic_float& operator=(const __atomic_float&) = delete;
-- 
2.25.1

Reply via email to