Skip to content

Commit 94538b8

Browse files
committed
rustc: Fix x86 ffi for struct arguments
This fixes struct passing abi on x86 ffi: Structs are now passed indirectly with byval attribute (as clang does).
1 parent 96e8c00 commit 94538b8

File tree

4 files changed

+21
-11
lines changed

4 files changed

+21
-11
lines changed

src/librustc/middle/trans/cabi_x86.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,14 @@ pub fn compute_abi_info(ccx: &CrateContext,
6262
ret_ty = ArgType::direct(rty, None, None, None);
6363
}
6464

65-
for &a in atys.iter() {
66-
arg_tys.push(ArgType::direct(a, None, None, None));
65+
for &t in atys.iter() {
66+
let ty = match t.kind() {
67+
Struct => {
68+
ArgType::indirect(t, Some(ByValAttribute))
69+
}
70+
_ => ArgType::direct(t, None, None, None),
71+
};
72+
arg_tys.push(ty);
6773
}
6874

6975
return FnType {

src/librustc/middle/trans/foreign.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,22 @@ pub fn register_foreign_item_fn(ccx: @CrateContext, abis: AbiSet,
145145
let llfn;
146146
{
147147
let mut externs = ccx.externs.borrow_mut();
148-
llfn = base::get_extern_fn(externs.get(),
148+
let externs = externs.get();
149+
let name = lname.get();
150+
let fn_exists = externs.contains_key_equiv(&name);
151+
llfn = base::get_extern_fn(externs,
149152
ccx.llmod,
150-
lname.get(),
153+
name,
151154
cc,
152155
llfn_ty,
153156
tys.fn_sig.output);
157+
if !fn_exists {
158+
// if function is already declared before get_extern_fn, it is bad to add attributes
159+
// because the declared one may have different signature. (see also #12707)
160+
// Add attributes only if they are declared just now.
161+
add_argument_attributes(&tys, llfn);
162+
}
154163
};
155-
add_argument_attributes(&tys, llfn);
156164

157165
llfn
158166
}

src/test/run-pass/extern-pass-TwoU16s.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// ignore-test #5744 fails on 32 bit
12-
1311
// Test a foreign function that accepts and returns a struct
1412
// by value.
1513

16-
#[deriving(Eq)]
14+
#[deriving(Eq, Show)]
1715
struct TwoU16s {
1816
one: u16, two: u16
1917
}

src/test/run-pass/extern-pass-TwoU8s.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// ignore-test #5744 fails on 32 bit
12-
1311
// Test a foreign function that accepts and returns a struct
1412
// by value.
1513

16-
#[deriving(Eq)]
14+
#[deriving(Eq, Show)]
1715
struct TwoU8s {
1816
one: u8, two: u8
1917
}

0 commit comments

Comments
 (0)