Fix a crash for 11 single byte fields passed through the C abi
Fixes #1234
This commit is contained in:
parent
c1ac2df0c3
commit
45b6cd6a8a
@ -124,6 +124,23 @@ fn call_return_u128_pair() {
|
||||
return_u128_pair();
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct bool_11 {
|
||||
field0: bool,
|
||||
field1: bool,
|
||||
field2: bool,
|
||||
field3: bool,
|
||||
field4: bool,
|
||||
field5: bool,
|
||||
field6: bool,
|
||||
field7: bool,
|
||||
field8: bool,
|
||||
field9: bool,
|
||||
field10: bool,
|
||||
}
|
||||
|
||||
extern "C" fn bool_struct_in_11(arg0: bool_11) {}
|
||||
|
||||
#[allow(unreachable_code)] // FIXME false positive
|
||||
fn main() {
|
||||
take_unique(Unique {
|
||||
@ -134,6 +151,20 @@ fn main() {
|
||||
|
||||
call_return_u128_pair();
|
||||
|
||||
bool_struct_in_11(bool_11 {
|
||||
field0: true,
|
||||
field1: true,
|
||||
field2: true,
|
||||
field3: true,
|
||||
field4: true,
|
||||
field5: true,
|
||||
field6: true,
|
||||
field7: true,
|
||||
field8: true,
|
||||
field9: true,
|
||||
field10: true,
|
||||
});
|
||||
|
||||
let slice = &[0, 1] as &[i32];
|
||||
let slice_ptr = slice as *const [i32] as *const i32;
|
||||
|
||||
|
@ -18,9 +18,9 @@ fn reg_to_abi_param(reg: Reg) -> AbiParam {
|
||||
let clif_ty = match (reg.kind, reg.size.bytes()) {
|
||||
(RegKind::Integer, 1) => types::I8,
|
||||
(RegKind::Integer, 2) => types::I16,
|
||||
(RegKind::Integer, 4) => types::I32,
|
||||
(RegKind::Integer, 8) => types::I64,
|
||||
(RegKind::Integer, 16) => types::I128,
|
||||
(RegKind::Integer, 3..=4) => types::I32,
|
||||
(RegKind::Integer, 5..=8) => types::I64,
|
||||
(RegKind::Integer, 9..=16) => types::I128,
|
||||
(RegKind::Float, 4) => types::F32,
|
||||
(RegKind::Float, 8) => types::F64,
|
||||
(RegKind::Vector, size) => types::I8.by(u16::try_from(size).unwrap()).unwrap(),
|
||||
@ -48,23 +48,9 @@ fn cast_target_to_abi_params(cast: CastTarget) -> SmallVec<[AbiParam; 2]> {
|
||||
)
|
||||
};
|
||||
|
||||
if cast.prefix.iter().all(|x| x.is_none()) {
|
||||
// Simplify to a single unit when there is no prefix and size <= unit size
|
||||
if cast.rest.total <= cast.rest.unit.size {
|
||||
let clif_ty = match (cast.rest.unit.kind, cast.rest.unit.size.bytes()) {
|
||||
(RegKind::Integer, 1) => types::I8,
|
||||
(RegKind::Integer, 2) => types::I16,
|
||||
(RegKind::Integer, 3..=4) => types::I32,
|
||||
(RegKind::Integer, 5..=8) => types::I64,
|
||||
(RegKind::Integer, 9..=16) => types::I128,
|
||||
(RegKind::Float, 4) => types::F32,
|
||||
(RegKind::Float, 8) => types::F64,
|
||||
(RegKind::Vector, size) => types::I8.by(u16::try_from(size).unwrap()).unwrap(),
|
||||
_ => unreachable!("{:?}", cast.rest.unit),
|
||||
};
|
||||
return smallvec![AbiParam::new(clif_ty)];
|
||||
}
|
||||
}
|
||||
// Note: Unlike the LLVM equivalent of this code we don't have separate branches for when there
|
||||
// is no prefix as a single unit, an array and a heterogeneous struct are not represented using
|
||||
// different types in Cranelift IR. Instead a single array of primitive types is used.
|
||||
|
||||
// Create list of fields in the main structure
|
||||
let mut args = cast
|
||||
|
Loading…
x
Reference in New Issue
Block a user