From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6600 invoked by alias); 30 Mar 2015 10:35:43 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 6553 invoked by uid 48); 30 Mar 2015 10:35:39 -0000 From: "redi at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/65147] alignment of std::atomic object is not correct Date: Mon, 30 Mar 2015 11:42:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: libstdc++ X-Bugzilla-Version: 4.9.2 X-Bugzilla-Keywords: ABI X-Bugzilla-Severity: normal X-Bugzilla-Who: redi at gcc dot gnu.org X-Bugzilla-Status: REOPENED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: 5.0 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2015-03/txt/msg03385.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65147 --- Comment #10 from Jonathan Wakely --- (In reply to Alexey Lapshin from comment #7) > It looks like this fix makes alignment of atomic object to be the same as > alignment of integral non-atomic object of the same size. Actually it only did that for non-integral atomic objects, e.g. I didn't do anything to change std::atomic. > The gcc behavior is different it makes alignment of atomic objects of sizes > 1,2,4,8,16 to match with size : That's not strictly true, there is a target hook (atomic_align_for_mode) which specifies the alignment for 1/2/4/8/16-byte objects, and the result is not necessarily the same as the size. Or so I'm told. That's why I used the nested conditional expressions with alignof(integral type) instead of just using alignas(sizeof(T)). > $g++ -latomic -std=c++11 -m32 all.cc > $./a.out > > sizeof(ac) 1 alignof(ac) 1 > sizeof(as) 2 alignof(as) 2 > sizeof(al) 4 alignof(al) 4 > sizeof(all) 8 alignof(all) 4 > sizeof(a16) 16 alignof(a16) 1 There are two problems here. The first is that alignof(std::atomic) is less than alignof(long long), and my recent changes didn't address that. That is easy to fix: --- a/libstdc++-v3/include/bits/atomic_base.h +++ b/libstdc++-v3/include/bits/atomic_base.h @@ -235,7 +235,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 8 bytes, since that is what GCC built-in functions for atomic // memory access expect. template - struct __atomic_base + struct alignas(_ITp) __atomic_base { private: typedef _ITp __int_type; The second problem is that alignof(struct S16) is not increased. That's because libstdc++ doesn't support __int128 on x86, so this bit of code doesn't do anything: #ifdef _GLIBCXX_USE_INT128 : sizeof(_Tp) == sizeof(__int128) ? alignof(__int128) #endif I'm not sure how to fix this. Maybe we should just bodge it like this and hope it is valid for all important targets: #ifdef _GLIBCXX_USE_INT128 : sizeof(_Tp) == sizeof(__int128) ? alignof(__int128) #else : sizeof(_Tp) == 16 ? 16 #endif (The real solution is a new attribute that uses the target hook, so we can guarantee the same result as the C front end, but it's too late to do that for GCC 5).