-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Clang: ABI incompatibility with MSVC on i686-windows for __declspec(align(N))
, with N <= 4
#63257
Comments
cc @rnk who implemented https://reviews.llvm.org/D72114. |
The text from the commit message describes the correct behavior: "remaining arguments with required alignment greater than 4 bytes are passed indirectly", but I guess there must be a bug in implementation. |
This code doesn't look right: It seems like we have a related bug if you move the alignment requirement from the RecordDecl to the FieldDecl: Clang passes directly, but MSVC passes indirectly. Ideally, we should pull the required alignment from the ASTRecordLayout, which has the RequiredAlign field and rolls up all the subobject alignment requirements, but I'm sure that will break something somewhere. |
I think MSVC is actually ignoring the requests to underalign the struct, see warning C4359, which you get if you move the declspec between This is a janky patch, but I think it will fix things:
The meaning of TypeInfo::AlignRequirement still seems underspecified. |
Should be fixed by 651e5ae |
Based on Piotr's findings. On MSVC i386 targets, structs requiring alignment greater than 4 are never passed by value. Clang follows the same behavior in MSVC mode (see [1] for details and [2] for a follow-up that applies this logic when fields, not necessarily the entire struct, are aligned). A number of ios functions take fpos_mbstatet as an argument and expect it to be passed by value. [1] https://reviews.llvm.org/D72114 [2] llvm/llvm-project#63257 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57817
For the following three struct definitions
when passed by value:
MSVC passes
NoRequestedAlign
andRequestedAlign1
on the stack (likebyval
), and passesRequestedAlign8
indirectly.Clang passes
NoRequestedAlign
on the stack (withbyval
), and passesRequestedAlign1
andRequestedAlign8
indirectly.It seems that Clang passes a struct indirectly if there is any
__declspec(align)
requested alignment, but MSVC only does so if the requested alignment is > 4.Demo: https://clang.godbolt.org/z/fsn78PhxT
The text was updated successfully, but these errors were encountered: