Closed
Description
struct SE {
virtual ~SE() = default;
virtual void oE() {}
};
struct WE : virtual SE {
~WE() override = default;
void oE() override;
};
struct FT : virtual WE {
~FT() override;
int m_b alignas(2 * sizeof(void*));
};
FT::~FT() {
m_b = 0;
}
$ clang --version
clang version 15.0.7
Target: x86_64-w64-windows-gnu
Thread model: posix
InstalledDir: D:/dep/msys64/ucrt64/bin
$ clang -O1 -target x86_64-windows repro.cpp -S -emit-llvm -o -
<snip>
define dso_local void @"??1FT@@UEAA@XZ"(ptr nocapture noundef nonnull align 16 dereferenceable(32) %0) unnamed_addr #
0 align 2 {
<snip>
%15 = getelementptr inbounds i8, ptr %0, i64 -24
store i32 0, ptr %15, align 16, !tbaa !7
ret void
}
<snip>
Note that both %0
and %15
are marked with align 16
even though the offset between them is 24 bytes.
This is much reduced with shortened identifiers so that I can still associate it with the original code. This bug manifested as optimized builds crashing at runtime on a movaps
instruction which was storing to a pointer that was not, in fact, 16 byte aligned, but which was derived from an 8-byte aligned pointer with an incorrectly marked alignment of 16 bytes and an offset that happened to be a multiple of 16 bytes.