ABI mismatch between rustc and clang for passing ZSTs using the win64 ABI. #132893
Open
Description
I tried this code:
https://clang.godbolt.org/z/eT5xEz757
rustc -O -C debuginfo=0 --target=x86_64-pc-windows-msvc
use std::ffi::c_int;
#[repr(C)]
pub struct Z {
v: [c_int; 0],
}
const _: () = assert!(std::mem::size_of::<Z>() == 0);
#[no_mangle]
extern "win64" fn f(a: Z, b: c_int) -> c_int {
let _ = a;
b + 1
}
#[no_mangle]
extern "win64" fn g(a: c_int) -> c_int {
a
}
clang -O -g0 --target=x86_64-pc-windows-gnu
struct Z {
int v[0];
};
_Static_assert(sizeof(struct Z) == 0, "Z should be a ZST");
int __attribute__((ms_abi)) f(struct Z a, int b) {
return b + 1;
}
int __attribute__((ms_abi)) g(int a) {
return a;
}
I expected to see this happen:
the generated assembly reads from the same register no matter if using clang or rustc.
Instead, this happened: rustc's f
reads from rcx
whereas clang's f
reads from rdx
.
Meta
rustc --version --verbose
:
rustc 1.82.0 (f6e511eec 2024-10-15)
binary: rustc
commit-hash: f6e511eec7342f59a25f7c0534f1dbea00d01b14
commit-date: 2024-10-15
host: x86_64-unknown-linux-gnu
release: 1.82.0
LLVM version: 19.1.1
It also does the exact same thing on:
rustc 1.84.0-nightly (b91a3a056 2024-11-07)
binary: rustc
commit-hash: b91a3a05609a46f73d23e0995ae7ebb4a4f429a5
commit-date: 2024-11-07
host: x86_64-unknown-linux-gnu
release: 1.84.0-nightly
LLVM version: 19.1.3
clang version: 19.1.0
Generated Assembly
clang's assembly:
f:
lea eax, [rdx + 1]
ret
g:
mov eax, ecx
ret
rustc's assembly
f:
lea eax, [rcx + 1]
ret
g:
mov eax, ecx
ret
Activity