Skip to content

Commit a51f76a

Browse files
committed
[beta] trans: pad const structs to aligned size
1 parent 85ca935 commit a51f76a

File tree

2 files changed

+39
-14
lines changed

2 files changed

+39
-14
lines changed

src/librustc_trans/adt.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -695,12 +695,9 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>, discr: D
695695
let lldiscr = C_integral(Type::from_integer(ccx, d), discr.0 as u64, true);
696696
let mut vals_with_discr = vec![lldiscr];
697697
vals_with_discr.extend_from_slice(vals);
698-
let mut contents = build_const_struct(ccx, &variant.offset_after_field[..],
699-
&vals_with_discr[..], variant.packed);
700-
let needed_padding = l.size(dl).bytes() - variant.min_size().bytes();
701-
if needed_padding > 0 {
702-
contents.push(padding(ccx, needed_padding));
703-
}
698+
let aligned_size = l.size(dl).bytes();
699+
let contents = build_const_struct(ccx, &variant.offset_after_field[..],
700+
&vals_with_discr[..], variant.packed, aligned_size);
704701
C_struct(ccx, &contents[..], false)
705702
}
706703
layout::UntaggedUnion { ref variants, .. }=> {
@@ -710,8 +707,9 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>, discr: D
710707
}
711708
layout::Univariant { ref variant, .. } => {
712709
assert_eq!(discr, Disr(0));
713-
let contents = build_const_struct(ccx,
714-
&variant.offset_after_field[..], vals, variant.packed);
710+
let aligned_size = l.size(dl).bytes();
711+
let contents = build_const_struct(ccx, &variant.offset_after_field[..],
712+
vals, variant.packed, aligned_size);
715713
C_struct(ccx, &contents[..], variant.packed)
716714
}
717715
layout::Vector { .. } => {
@@ -727,10 +725,11 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>, discr: D
727725
}
728726
}
729727
layout::StructWrappedNullablePointer { ref nonnull, nndiscr, .. } => {
728+
let aligned_size = l.size(dl).bytes();
730729
if discr.0 == nndiscr {
731730
C_struct(ccx, &build_const_struct(ccx,
732731
&nonnull.offset_after_field[..],
733-
vals, nonnull.packed),
732+
vals, nonnull.packed, aligned_size),
734733
false)
735734
} else {
736735
let fields = compute_fields(ccx, t, nndiscr as usize, false);
@@ -742,7 +741,8 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>, discr: D
742741
C_struct(ccx, &build_const_struct(ccx,
743742
&nonnull.offset_after_field[..],
744743
&vals[..],
745-
false),
744+
false,
745+
aligned_size),
746746
false)
747747
}
748748
}
@@ -761,7 +761,8 @@ pub fn trans_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>, discr: D
761761
fn build_const_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
762762
offset_after_field: &[layout::Size],
763763
vals: &[ValueRef],
764-
packed: bool)
764+
packed: bool,
765+
aligned_size: u64)
765766
-> Vec<ValueRef> {
766767
assert_eq!(vals.len(), offset_after_field.len());
767768

@@ -787,9 +788,8 @@ fn build_const_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
787788
}
788789
}
789790

790-
let size = offset_after_field.last().unwrap();
791-
if offset < size.bytes() {
792-
cfields.push(padding(ccx, size.bytes() - offset));
791+
if offset < aligned_size {
792+
cfields.push(padding(ccx, aligned_size - offset));
793793
}
794794

795795
cfields

src/test/run-pass/issue-37222.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#[derive(Debug, PartialEq)]
12+
enum Bar {
13+
A(i64),
14+
B(i32),
15+
C,
16+
}
17+
18+
#[derive(Debug, PartialEq)]
19+
struct Foo(Bar, u8);
20+
21+
static FOO: [Foo; 2] = [Foo(Bar::C, 0), Foo(Bar::C, 0xFF)];
22+
23+
fn main() {
24+
assert_eq!(&FOO[1], &Foo(Bar::C, 0xFF));
25+
}

0 commit comments

Comments
 (0)