Open tschuett opened 4 years ago
Listing the alignment and access size (== expected alignment) in the warning seems like a good idea.
Maybe extend the warning: The pointer is 8 byte aligned, while the value requires an alignment of 16 bytes.
I read through the source code and finally found the ASTRecordLayout. Then I realized that it is aligned on Foo::Bar::a, which is only 8 bytes. The 16 bytes is my misunderstanding.
But the error makes it hard to find the root cause. The root cause is not even visible in the expression: __atomic_load(&foo->bar, &dummy, __ATOMIC_RELAXED); It is foo->bar.a.
clang believes that the pointer is 8 byte aligned, but foo->bar is actually 16 byte aligned.
Why do you believe that to be the case?
"misaligned atomic operation may incur significant performance penalty" This sentence is always true, but it is not actionable. It does not help me to solve the problem.
I am starting to understand the problem. Foo is aligned on Foo::Bar::a. Thus the alignment of Foo is 8 bytes. Foo * is not aligned on Foo::Bar. But the error message is still confusing as it took me a while to find out what is misaligned.
The following solves my problem.
struct Foo { struct alignas (16) Bar { uint64_t a; uint64_t b; }; Bar bar; };
Even void braz(Foo foo) { Foo::Bar dummy; __atomic_load((Foo::Bar )foo, &dummy, __ATOMIC_RELAXED); }
gives warnings.
I added printf statements to CGAtomic.cpp and the inferred alignment is 8 bytes and sizeChars is 16 byte.
Extended Description
For the following code, I get an error: repro.cpp:13:3: warning: misaligned atomic operation may incur significant performance penalty [-Watomic-alignment] __atomic_load(&foo->bar, &dummy, __ATOMIC_RELAXED);
clang believes that the pointer is 8 byte aligned, but foo->bar is actually 16 byte aligned.
include
struct Foo { struct Bar { uint64_t a; uint64_t b; }; Bar bar; };
void braz(Foo *foo) { Foo::Bar dummy; __atomic_load(&foo->bar, &dummy, __ATOMIC_RELAXED); }