===================================================================
@@ -165,16 +165,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct atomic
{
private:
- // Align 1/2/4/8/16-byte types the same as integer types of that size.
+ // Align 1/2/4/8/16-byte types to the natural alignment of that size.
// This matches the alignment effects of the C11 _Atomic qualifier.
static constexpr int _S_min_alignment
- = sizeof(_Tp) == sizeof(char) ? alignof(char)
- : sizeof(_Tp) == sizeof(short) ? alignof(short)
- : sizeof(_Tp) == sizeof(int) ? alignof(int)
- : sizeof(_Tp) == sizeof(long) ? alignof(long)
- : sizeof(_Tp) == sizeof(long long) ? alignof(long long)
+ = sizeof(_Tp) == sizeof(char) ? max(sizeof(char), alignof(char))
+ : sizeof(_Tp) == sizeof(short) ? max(sizeof(short), alignof(short))
+ : sizeof(_Tp) == sizeof(int) ? max(sizeof(int), alignof(int))
+ : sizeof(_Tp) == sizeof(long) ? max(sizeof(long), alignof(long))
+ : sizeof(_Tp) == sizeof(long long) ? max(sizeof(long long), alignof(long long))
#ifdef _GLIBCXX_USE_INT128
- : sizeof(_Tp) == sizeof(__int128) ? alignof(__int128)
+ : sizeof(_Tp) == sizeof(__int128) ? max(sizeof(__int128), alignof(__int128))
#endif
: 0;
@@ -216,7 +216,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
is_lock_free() const noexcept
{
// Produce a fake, minimally aligned pointer.
- void *__a = reinterpret_cast<void *>(-__alignof(_M_i));
+ void *__a = reinterpret_cast<void *>(-_S_alignment);
return __atomic_is_lock_free(sizeof(_M_i), __a);
}
@@ -224,7 +224,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
is_lock_free() const volatile noexcept
{
// Produce a fake, minimally aligned pointer.
- void *__a = reinterpret_cast<void *>(-__alignof(_M_i));
+ void *__a = reinterpret_cast<void *>(-_S_alignment);
return __atomic_is_lock_free(sizeof(_M_i), __a);
}
===================================================================
@@ -240,7 +240,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private:
typedef _ITp __int_type;
- __int_type _M_i;
+ // Align 1/2/4/8/16-byte types to the natural alignment of that size.
+ // This matches the alignment effects of the C11 _Atomic qualifier.
+ static constexpr int _S_min_alignment
+ = sizeof(_Tp) == sizeof(char) ? max(sizeof(char), __alignof(char))
+ : sizeof(_Tp) == sizeof(short) ? max(sizeof(short), __alignof(short))
+ : sizeof(_Tp) == sizeof(int) ? max(sizeof(int), __alignof(int))
+ : sizeof(_Tp) == sizeof(long) ? max(sizeof(long), __alignof(long))
+ : sizeof(_Tp) == sizeof(long long) ? max(sizeof(long long), __alignof(long long))
+#ifdef _GLIBCXX_USE_INT128
+ : sizeof(_Tp) == sizeof(__int128) ? max(sizeof(__int128), __alignof(__int128))
+#endif
+ : 0;
+
+ static constexpr int _S_alignment
+ = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : __alignof(_Tp);
+
+ __int_type _M_i __attribute ((__aligned(_S_alignment)));
public:
__atomic_base() noexcept = default;
@@ -348,7 +364,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
is_lock_free() const noexcept
{
// Produce a fake, minimally aligned pointer.
- void *__a = reinterpret_cast<void *>(-__alignof(_M_i));
+ void *__a = reinterpret_cast<void *>(-_S_alignment);
return __atomic_is_lock_free(sizeof(_M_i), __a);
}
@@ -356,7 +372,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
is_lock_free() const volatile noexcept
{
// Produce a fake, minimally aligned pointer.
- void *__a = reinterpret_cast<void *>(-__alignof(_M_i));
+ void *__a = reinterpret_cast<void *>(-_S_alignment);
return __atomic_is_lock_free(sizeof(_M_i), __a);
}