This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/62259] New: atomic class doesn't enforce required alignment on powerpc64
- From: "saugustine at google dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 25 Aug 2014 20:06:15 +0000
- Subject: [Bug libstdc++/62259] New: atomic class doesn't enforce required alignment on powerpc64
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62259
Bug ID: 62259
Summary: atomic class doesn't enforce required alignment on
powerpc64
Product: gcc
Version: 4.9.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: saugustine at google dot com
Created attachment 33396
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33396&action=edit
small reproducer
The attached short program results in a bus error on powerpc64 top of trunk at
-O0, but I believe is a bug that would be exposed on many targets, going back
at least to 4.9.
It succeeds--probably by luck--on 4.8.
The key is that the atomic struct is eight-bytes in size, but only four byte
aligned, and gcc takes no care to subsequently align it. GCC chooses an ldarx
instruction, which requires eight-byte alignment.
Although https://gcc.gnu.org/wiki/Atomic/GCCMM/UnalignedPolicy doesn't directly
address this case, a careful reading leads me to believe that this is intended
to work.
My uneducated guess is that the template at <atomic>:189 should either use
&_M_i in calls to __atomic_is_lock_free (instead of nullptr) or should add
alignment as necessary. Not sure how that is intended to be done. If I fix
<atomic> to pass the pointer, then gcc chooses to call out to an atomic library
function, which gcc doesn't provide.
google ref b/17136920
g++ -std=c++11 t.cc -O0
#include <atomic>
struct twoints {
int a;
int b;
};
int main() {
// unalign subsequent variables
char b0 = 'a';
twoints one = { 1 };
twoints two = { 2 };
std::atomic<twoints> a(one);
twoints e = { 0 };
a.compare_exchange_strong(e, two, std::memory_order_acq_rel);
return 0;
}