about summary refs log tree commit diff
path: root/src/librustc_codegen_ssa
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2018-11-24 01:31:56 +0800
committerGitHub <noreply@github.com>2018-11-24 01:31:56 +0800
commite0025df3fdfa8be82946a6e861049bae932eba75 (patch)
treee67262c792f3aa23e2a183f52098982e2bdc42c5 /src/librustc_codegen_ssa
parentfb33fa49160f666d1cad0af6c275e15cf523e047 (diff)
parent4c21f66c1dffefa0dbeec3e409aa77630cb9a448 (diff)
downloadrust-e0025df3fdfa8be82946a6e861049bae932eba75.tar.gz
rust-e0025df3fdfa8be82946a6e861049bae932eba75.zip
Rollup merge of #56097 - ogoffart:union-abi, r=eddyb
Fix invalid bitcast taking bool out of a union represented as a scalar

As reported in https://github.com/rust-lang/rust/pull/54668#issuecomment-440186476
Diffstat (limited to 'src/librustc_codegen_ssa')
-rw-r--r--src/librustc_codegen_ssa/mir/operand.rs17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs
index f6917906d4a..92d0219caf0 100644
--- a/src/librustc_codegen_ssa/mir/operand.rs
+++ b/src/librustc_codegen_ssa/mir/operand.rs
@@ -244,13 +244,24 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> {
         };
 
         // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
+        // Bools in union fields needs to be truncated.
+        let to_immediate_or_cast = |bx: &mut Bx, val, ty| {
+            if ty == bx.cx().type_i1() {
+                bx.trunc(val, ty)
+            } else {
+                bx.bitcast(val, ty)
+            }
+        };
+
         match val {
             OperandValue::Immediate(ref mut llval) => {
-                *llval = bx.bitcast(*llval, bx.cx().immediate_backend_type(field));
+                *llval = to_immediate_or_cast(bx, *llval, bx.cx().immediate_backend_type(field));
             }
             OperandValue::Pair(ref mut a, ref mut b) => {
-                *a = bx.bitcast(*a, bx.cx().scalar_pair_element_backend_type(field, 0, true));
-                *b = bx.bitcast(*b, bx.cx().scalar_pair_element_backend_type(field, 1, true));
+                *a = to_immediate_or_cast(bx, *a, bx.cx()
+                    .scalar_pair_element_backend_type(field, 0, true));
+                *b = to_immediate_or_cast(bx, *b, bx.cx()
+                    .scalar_pair_element_backend_type(field, 1, true));
             }
             OperandValue::Ref(..) => bug!()
         }