Skip to content

Commit 86d4135

Browse files
committed
Fix invalid bitcast taking bool out of a union represented as a scalar
As reported in #54668 (comment)
1 parent 046e054 commit 86d4135

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

src/librustc_codegen_ssa/mir/operand.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,14 +243,22 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> {
243243
_ => bug!("OperandRef::extract_field({:?}): not applicable", self)
244244
};
245245

246+
let bitcast = |bx: &mut Bx, val, ty| {
247+
if ty == bx.cx().type_i1() {
248+
bx.trunc(val, ty)
249+
} else {
250+
bx.bitcast(val, ty)
251+
}
252+
};
253+
246254
// HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
247255
match val {
248256
OperandValue::Immediate(ref mut llval) => {
249-
*llval = bx.bitcast(*llval, bx.cx().immediate_backend_type(field));
257+
*llval = bitcast(bx, *llval, bx.cx().immediate_backend_type(field));
250258
}
251259
OperandValue::Pair(ref mut a, ref mut b) => {
252-
*a = bx.bitcast(*a, bx.cx().scalar_pair_element_backend_type(field, 0, true));
253-
*b = bx.bitcast(*b, bx.cx().scalar_pair_element_backend_type(field, 1, true));
260+
*a = bitcast(bx, *a, bx.cx().scalar_pair_element_backend_type(field, 0, true));
261+
*b = bitcast(bx, *b, bx.cx().scalar_pair_element_backend_type(field, 1, true));
254262
}
255263
OperandValue::Ref(..) => bug!()
256264
}

src/test/codegen/union-abi.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,9 @@ pub union CUnionU128{a:u128}
7878
#[no_mangle]
7979
pub fn test_CUnionU128(_: CUnionU128) { loop {} }
8080

81+
pub union UnionBool { b:bool }
82+
// CHECK: define zeroext i1 @test_UnionBool(i8 %b)
83+
#[no_mangle]
84+
pub fn test_UnionBool(b: UnionBool) -> bool { unsafe { b.b } }
85+
// CHECK: %0 = trunc i8 %b to i1
86+

0 commit comments

Comments
 (0)