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

Reply via email to