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