about summary refs log tree commit diff
path: root/src/librustc_codegen_ssa
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2018-12-21 23:12:15 +0100
committerNikita Popov <nikita.ppv@gmail.com>2018-12-21 23:51:55 +0100
commit097d39d8ecb2d8aa828393c66e85716081188793 (patch)
treeaa2379ca26f87947862b7528cd3087e04c092f27 /src/librustc_codegen_ssa
parent6d34ec18c7d7e574553f6347ecf08e1e1c45c13d (diff)
downloadrust-097d39d8ecb2d8aa828393c66e85716081188793.tar.gz
rust-097d39d8ecb2d8aa828393c66e85716081188793.zip
Fix alignment for array indexing
We need to reduce the alignment with the used offset. If the offset
isn't known, we need to reduce with the element size to support
arbitrary offsets.
Diffstat (limited to 'src/librustc_codegen_ssa')
-rw-r--r--src/librustc_codegen_ssa/mir/place.rs13
-rw-r--r--src/librustc_codegen_ssa/mir/rvalue.rs3
2 files changed, 13 insertions, 3 deletions
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index 90aa9f6cbc7..5fad4a24b26 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -335,11 +335,20 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> {
         bx: &mut Bx,
         llindex: V
     ) -> Self {
+        // Statically compute the offset if we can, otherwise just use the element size,
+        // as this will yield the lowest alignment.
+        let layout = self.layout.field(bx, 0);
+        let offset = if bx.is_const_integral(llindex) {
+            layout.size.checked_mul(bx.const_to_uint(llindex), bx).unwrap_or(layout.size)
+        } else {
+            layout.size
+        };
+
         PlaceRef {
             llval: bx.inbounds_gep(self.llval, &[bx.cx().const_usize(0), llindex]),
             llextra: None,
-            layout: self.layout.field(bx.cx(), 0),
-            align: self.align
+            layout,
+            align: self.align.restrict_for_offset(offset),
         }
     }
 
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index c932ffd1c1b..052342dd759 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -131,8 +131,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 let keep_going = header_bx.icmp(IntPredicate::IntNE, current, end);
                 header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb());
 
+                let align = dest.align.restrict_for_offset(dest.layout.field(bx.cx(), 0).size);
                 cg_elem.val.store(&mut body_bx,
-                    PlaceRef::new_sized(current, cg_elem.layout, dest.align));
+                    PlaceRef::new_sized(current, cg_elem.layout, align));
 
                 let next = body_bx.inbounds_gep(current, &[bx.cx().const_usize(1)]);
                 body_bx.br(header_bx.llbb());