-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Swapped Arguments in Generated Code for extern-C func on x64 #41375
Comments
You might also need |
Looks like we use EDIT: adding one more |
Arg9 should be passed in r9. Since we expect it as %UsizeArg9* that's not happening. |
That matches my conclusion. |
Looks like we're treating stack arguments as using up registers (not just the return pointer). Minimal reproduction of the provided testcase (6 stack arguments, 1 register argument): #![crate_type="staticlib"]
#[repr(C)] pub struct Big { data: [u8; 64] }
#[repr(C)] pub struct Small { data: u8 }
#[no_mangle]
pub extern "C" fn test(_: Big, _: Big, _: Big, _: Big, _: Big, _: Big, s: Small) {
println!("{}", s.data);
} typedef struct { unsigned char data[64]; } Big;
typedef struct { unsigned char data; } Small;
void test(Big, Big, Big, Big, Big, Big, Small);
int main() {
Big big;
Small small = { 42 };
test(big, big, big, big, big, big, small);
} |
Testcase for Rust -> C call (roughly what will end up in #[repr(C)]
#[derive(Copy, Clone)]
struct Big { data: [i32; 5] }
#[repr(C)]
struct Small { data: i32 }
extern "C" {
fn test(a: Big, b: Big, c: Big, d: Big, e: Big, f: Big, g: Small);
}
fn main() {
let big = Big { data: [0; 5] };
unsafe {
test(big, big, big, big, big, big, Small { data: 42 });
}
} #include <assert.h>
#include <stdint.h>
typedef struct { int32_t data[5]; } Big;
typedef struct { int32_t data; } Small;
void test(Big a, Big b, Big c, Big d, Big e, Big f, Small g) {
assert(g.data == 42);
} |
…elb1 rustc_trans: do not treat byval as using up registers. Perhaps not that well-documented, `byval` pointer arguments *are not* the same as pointer arguments used by pass-by-ref, but rather the pointer is only used by LLVM to pass the *contents* on the stack. Fixes rust-lang#41375.
…elb1 rustc_trans: do not treat byval as using up registers. Perhaps not that well-documented, `byval` pointer arguments *are not* the same as pointer arguments used by pass-by-ref, but rather the pointer is only used by LLVM to pass the *contents* on the stack. Fixes rust-lang#41375.
…elb1 rustc_trans: do not treat byval as using up registers. Perhaps not that well-documented, `byval` pointer arguments *are not* the same as pointer arguments used by pass-by-ref, but rather the pointer is only used by LLVM to pass the *contents* on the stack. Fixes rust-lang#41375.
…elb1 rustc_trans: do not treat byval as using up registers. Perhaps not that well-documented, `byval` pointer arguments *are not* the same as pointer arguments used by pass-by-ref, but rather the pointer is only used by LLVM to pass the *contents* on the stack. Fixes rust-lang#41375.
…elb1 rustc_trans: do not treat byval as using up registers. Perhaps not that well-documented, `byval` pointer arguments *are not* the same as pointer arguments used by pass-by-ref, but rather the pointer is only used by LLVM to pass the *contents* on the stack. Fixes rust-lang#41375.
The following program has arg9 and arg10 swapped on the Rust side (C++ is passing the args correctly, as far as the AMD64 ABI is concerned).
Test Platform: macos x64
Reproduced On:
Reproduction Steps:
The text was updated successfully, but these errors were encountered: