-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
i128 / u128 are not compatible with C's definition. #54341
Comments
I think the correct fix would be to add I guess that's probably not hard? I could have a go at that if it sounds like the right thing to do. |
This is a bug in llvm. There was an attempt to fix this in the past, but it got reverted because of reasons. The sysV __int128 should be 16-byte aligned and rust follows that ABI. |
Rather, this is blocked on LLVM data-layouts getting fixed, because rustc expects them to be matched last time I checked. |
Ugh, thanks @nagisa... I think this is also a problem for #include <stdio.h>
struct foo {
long double bar;
};
int main() {
printf("%ld\n", _Alignof(struct foo)); // 16
} |
To work-around some cases of rust-lang/rust#54341. Other cases where u128 and u64 are mixed in fields might not behave correctly, but the field offset assertions would catch them. Fixes rust-lang#1370
Copying from the last thread, since this thread seems to mostly be about long double. In C and C++, on x86_64 Linux, alignof(__int128) is equal to 16. However, in Rust, align_of::() is equal to 8. C++: https://gcc.godbolt.org/z/YAq1XC This will cause subtle UB if you ever try to use i128s across FFI boundaries; for example: C++: https://gcc.godbolt.org/z/PrtHlp |
The |
Why that? Rust itself is sound. The types are not FFI-safe, but FFI needs unsafe code. |
Using |
This can be generalized for any Just to be entirely clear: even if we fixed this particular issue for x86_64 SysV targets, it will only make u128 matching with other x86_64 SysV-abiding artifacts. For most other targets the fact that i/u128 ABI is not specified or is implementation-specific will remain. And so this type can never get any more guarantees than what it currently gets. |
AFAIK all 64-bit targets except for MSVC have a defined
That means that the layout of these types is unspecified, which prevents users from using What's the rationale for not providing a layout that's compatible with |
EDIT: NVM, for the integer types, |
Nobody argued that we should have a different layout. I agree using a different layout is a bug. I just don't agree it's a soundness bug.
Ultimately where to draw the line for soundness bugs can be arbitrary though. |
Is anyone working on fixing this? |
The reason is that |
@gnzlbg but why isn't it FFI safe? |
See: #54341 (comment) |
So which targets do have a defined call ABI for passing 128-bit integers? You said everything except the MSVC targets, at least. (EDIT: corrected.) It was my understanding that this is blocked on LLVM bugs. Not sure if there is an LLVM issue tracking this. But now it sounds more like this is blocked on Rust needing a target-dependent notion of "FFI safe"? |
I don't know of any target that doesn't. I also can't imagine a target for which not having this documented on its ABI wouldn't be considered an ABI spec bug.
I said that the msvc compiler is the only widely-used C compiler I know that does not have an If all these other compilers for this target agree, then there is an ABI for |
There might be targets without an ABI spec and/or without C compilers, in which case, we can try to agree with whatever is used on the target, but if that doesn't support 128-bit integers, does it even matter what we do? |
Most 32 bit C toolchains don't have |
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. See rust-lang#54341 add missing windows targets
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. See rust-lang#54341
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. See rust-lang#54341
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. See rust-lang#54341
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. See rust-lang#54341
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. See rust-lang#54341
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. See rust-lang#54341
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. This alignment change was discussed in rust-lang/compiler-team#683 See rust-lang#54341 for additional information about why this is happening and where this will be useful in the future. This *does not* stabilize `i128`/`u128` for FFI.
LLVM 18 x86 data layout update With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. See rust-lang#54341
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. See rust-lang#54341
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. This alignment change was discussed in rust-lang/compiler-team#683 See rust-lang#54341 for additional information about why this is happening and where this will be useful in the future. This *does not* stabilize `i128`/`u128` for FFI.
LLVM 18 x86 data layout update With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. See rust-lang#54341
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. This alignment change was discussed in rust-lang/compiler-team#683 See rust-lang#54341 for additional information about why this is happening and where this will be useful in the future. This *does not* stabilize `i128`/`u128` for FFI.
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. This alignment change was discussed in rust-lang/compiler-team#683 See rust-lang#54341 for additional information about why this is happening and where this will be useful in the future. This *does not* stabilize `i128`/`u128` for FFI.
LLVM 18 x86 data layout update With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. See rust-lang#54341
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. This alignment change was discussed in rust-lang/compiler-team#683 See rust-lang#54341 for additional information about why this is happening and where this will be useful in the future. This *does not* stabilize `i128`/`u128` for FFI.
LLVM 18 x86 data layout update With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and removes the alignment when speaking to older LLVM. This results in Rust overaligning things relative to LLVM on older LLVMs. This implements MCP rust-lang/compiler-team#683. See rust-lang#54341
With https://reviews.llvm.org/D86310 LLVM now has i128 aligned to 16-bytes on x86 based platforms. This will be in LLVM-18. This patch updates all our spec targets to be 16-byte aligned, and ignores the alignment change when checking what the LLVM's default spec is on the relevant targets for older LLVMs. * This is a potentially breaking change, as u128 and i128 will have their alignment increase on some platforms. * This results in Rust overaligning things relative to LLVM on older LLVMs. See rust-lang#54341
Latest status: this is fixed in latest Rust with the latest LLVM (default starting with 1.78), see https://blog.rust-lang.org/2024/03/30/i128-layout-update.html. We still need to figure out what to do with the improper_ctypes lint since there are broken conditions with older LLVM versions, see rust-lang/lang-team#255. I think it is okay to close this huge issue and just track the lint changes at at the lang team issue. |
All right, let's close this then. :) Thanks a lot to everyone who worked on fixing this long-standing problem! |
The `aarch64` and `x86_64` architectures have alignment differences for `u128` type: * `aarch64` has 16 bytes alignment * `x86_64` has 8 bytes aligment In order to fix the issue we're going to use `[u8; 16]` instead of `u128`, which will always have alignment of 8 bytes and have backwards compatibility with existing `x86_64` serialized data. See the following issues for more details: * rust-lang/rust#54949 * rkyv/rkyv#409 * rust-lang/rust#54341
While fixing various bindgen bugs related to
long double
,int128
, (rust-lang/rust-bindgen#1370, etc).I realized that the following Rust program, in my x86_64 Linux machine:
Prints
8
.While the following C program:
Prints
16
on the same system. This is pretty unexpected, and means that i128 / u128 are not really usable for FFI / alignment purposes.The text was updated successfully, but these errors were encountered: