https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71660
Bug ID: 71660
Summary: [4.9 regression] alignment of std::atomic<8 byte
primitive type> (long long, double) is wrong on x86
Product: gcc
Version: 6.1.1
Status: UNCONFIRMED
Severity: major
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: thiago at kde dot org
Target Milestone: ---
The resolution of Bug 65147 made this change to __atomic_base:
- __int_type _M_i;
+ static constexpr int _S_alignment =
+ sizeof(_ITp) > alignof(_ITp) ? sizeof(_ITp) : alignof(_ITp);
+
+ alignas(_S_alignment) __int_type _M_i;
That breaks the alignment for 8-byte primitive types on 32-bit x86, which have
a historical under-alignment to keep ABI compatibility with existing code.
That is:
alignof(long long) == 8
but:
struct InStruct { long long x; }
alignof(InStruct) == 4
The above is done so that existing structures containing those types retain
their layout.
Prior to Commit 221945, this struct had alignment of 4 on x86:
struct AtomicStruct { int; std::atomic<long long> x; };
After it, it's now 8.
More importantly, the sizeof that struct changed from 12 to 16 and the layout
also changed.
Please update this change to exclude:
long long
unsigned long long
double
long double