-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[Clang] Crash when building trivial C++ code on PowerPC (32-bit) #111993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
On big-endian systems, narrow casting will read the higher bits of the value. LazyOffsetPtr's `getAddressOfPointer` returns the address-of `Ptr` which was unconditionally a 64-bit value. On 32-bit big endian systems, reading this value as a 32-bit pointer returns invalid data. Fixes: bc73ef0 ("PR60985: Fix merging of lambda closure types across modules.") Closes: llvm#111993
@llvm/issue-subscribers-clang-frontend Author: A. Wilcox (awilfox)
While building Clang 17, 18, and 19 natively on 32-bit PowerPC, I encountered over 500 test failures:
All of them look similar to:
I enabled ASan and UBSan - which was extremely difficult to fit in the 4 GB binary size limit on a 32-bit platform, but I managed it - and found no real useful information other than the address was oddly set to 0xffffffff: <details><summary>ASan output</summary>
</p> <details><summary>UBSan output</summary>
</p> Clang 16 works fine, so I bisected through: <details><summary>Bisection log</summary>
</p> and found that #60985 was the culprit. Looking at the code, I immediately saw the issue. The |
Hi I am new here and would like to work on this issue. Could you please assign this to me? Will try my best to resolve it. |
@minhlongng123 There's already a PR for it at #111995. |
/cherry-pick 7619699 |
/pull-request #113052 |
LazyOffsetPtr currently relies on uint64_t being able to store a pointer and, unless sizeof(uint64_t) == sizeof(void *), little endianness, since getAddressOfPointer reinterprets the memory as a pointer. This also doesn't properly respect the C++ object model. As removing getAddressOfPointer would have wide-reaching implications, improve the implementation to account for these problems by using placement new and a suitably sized-and-aligned buffer, "right"-aligning the objects on big-endian platforms so the LSBs are in the same place for use as the discriminator. Fixes: bc73ef0 Fixes: llvm#111993 (cherry picked from commit 7619699)
While building Clang 17, 18, and 19 natively on 32-bit PowerPC, I encountered over 500 test failures:
All of them look similar to:
I enabled ASan and UBSan - which was extremely difficult to fit in the 4 GB binary size limit on a 32-bit platform, but I managed it - and found no real useful information other than the address was oddly set to 0xffffffff:
ASan output
UBSan output
Clang 16 works fine, so I bisected through:
Bisection log
and found that #60985 was the culprit. Looking at the code, I immediately saw the issue. The
Ptr
value inLazyOffsetPtr
is 64-bits (uint64_t
), and the new methodgetAddressOfPointer
returns a reference toPtr
as a pointer-to-pointer. The problem is that on 32-bit big endian platforms (such as PPC), pointing toPtr
will read the top 32 bits of the value, not the bottom 32 bits.The text was updated successfully, but these errors were encountered: