Change:
See run-pass/extern-pass- and run_pass/extern-
it seems to be related to issue .
Still reproduces.
These appear to have been fixed as part of
Closing an issue without un-xfailing the tests! The horror! (I'm landing the un-xfail in .)
Aaaaaand, it looks like this isn't fixed:
gah sorry! I was looking at instead of . My bad.
triage: still broken

Discussion:
/// LLVM type or by coercing to another specified type Direct, /// Pass the argument indirectly via a hidden pointer <del> Indirect </del> <ins> Indirect, /// Ignore the argument (useful for empty struct) Ignore, </ins> } /// Information about how a specific C type

} } <ins> pub fn ignore(ty: Type) -> ArgType { ArgType { kind: Ignore, ty: ty, cast: None, pad: None, attr: None, } } </ins> pub fn is_direct(&self) -> bool { return self.kind == Direct; }

pub fn is_indirect(&self) -> bool { return self.kind == Indirect; } <ins> pub fn is_ignore(&self) -> bool { return self.kind == Ignore; } </ins> } /// Metadata describing how the arguments to a native function

for &t in atys.iter() { let ty = match t.kind() { Struct => { <del> ArgType::indirect(t, Some(ByValAttribute)) </del> <ins> let size = llsize_of_alloc(ccx, t); if size == 0 { ArgType::ignore(t) } else { ArgType::indirect(t, Some(ByValAttribute)) } </ins> } _ => ArgType::direct(t, None, None, None), };

for (i, &llarg_rust) in llargs_rust.iter().enumerate() { let mut llarg_rust = llarg_rust; <ins> if arg_tys[i].is_ignore() { continue; } </ins> // Does Rust pass this argument by pointer? let rust_indirect = type_of::arg_is_indirect(ccx, *passed_arg_tys.get(i));

}; for &arg_ty in tys.fn_ty.arg_tys.iter() { <ins> if arg_ty.is_ignore() { continue; } </ins> // add padding match arg_ty.pad { Some(ty) => llargument_tys.push(ty),

} for &arg_ty in tys.fn_ty.arg_tys.iter() { <ins> if arg_ty.is_ignore() { continue; } </ins> // skip padding if arg_ty.pad.is_some() { i += 1; }

return u; } <ins> struct ManyInts { int8_t arg1; int16_t arg2; int32_t arg3; int16_t arg4; int8_t arg5; struct TwoU8s arg6; }; struct Empty { }; void rust_dbg_extern_empty_struct(struct ManyInts v1, struct Empty e, struct ManyInts v2) { assert(v1.arg1 == v2.arg1 + 1); assert(v1.arg2 == v2.arg2 + 1); assert(v1.arg3 == v2.arg3 + 1); assert(v1.arg4 == v2.arg4 + 1); assert(v1.arg5 == v2.arg5 + 1); assert(v1.arg6.one == v2.arg6.one + 1); assert(v1.arg6.two == v2.arg6.two + 1); } </ins> intptr_t rust_get_test_int() { return 1;

<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // Test a foreign function that accepts empty struct. struct TwoU8s { one: u8, two: u8, } struct ManyInts { arg1: i8, arg2: i16, arg3: i32, arg4: i16, arg5: i8, arg6: TwoU8s, } struct Empty; #[link(name = "rustrt")] extern { fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts); } pub fn main() { unsafe { let x = ManyInts { arg1: 2, arg2: 3, arg3: 4, arg4: 5, arg5: 6, arg6: TwoU8s { one: 7, two: 8, } }; let y = ManyInts { arg1: 1, arg2: 2, arg3: 3, arg4: 4, arg5: 5, arg6: TwoU8s { one: 6, two: 7, } }; let empty = Empty; rust_dbg_extern_empty_struct(x, empty, y); } } </ins>