1 // Copyright 2017 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.
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 #![feature(attr_literals)]
11 #![feature(repr_align)]
19 // Lowering has no effect
23 // Multiple attributes take the max
27 struct AlignMany(i32);
29 // Raising alignment may not alter size.
45 // Nested alignment - use `#[repr(C)]` to suppress field reordering for sizeof test
58 struct AlignContainsPacked {
64 // return aligned type
65 pub fn new(i: i32) -> Align16 {
69 pub fn consume(a: Align16) -> i32 {
74 const CONST_ALIGN16: Align16 = Align16(7);
75 static STATIC_ALIGN16: Align16 = Align16(8);
77 // Check the actual address is aligned
78 fn is_aligned_to<T>(p: &T, align: usize) -> bool {
79 let addr = p as *const T as usize;
80 (addr & (align - 1)) == 0
84 // check alignment and size by type and value
85 assert_eq!(mem::align_of::<Align16>(), 16);
86 assert_eq!(mem::size_of::<Align16>(), 16);
90 assert_eq!(mem::align_of_val(&a), 16);
91 assert_eq!(mem::size_of_val(&a), 16);
93 assert!(is_aligned_to(&a, 16));
95 // lowering should have no effect
96 assert_eq!(mem::align_of::<Align1>(), 4);
97 assert_eq!(mem::size_of::<Align1>(), 4);
100 assert_eq!(mem::align_of_val(&a), 4);
101 assert_eq!(mem::size_of_val(&a), 4);
102 assert!(is_aligned_to(&a, 4));
104 // when multiple attributes are specified the max should be used
105 assert_eq!(mem::align_of::<AlignMany>(), 16);
106 assert_eq!(mem::size_of::<AlignMany>(), 16);
107 let a = AlignMany(7);
109 assert_eq!(mem::align_of_val(&a), 16);
110 assert_eq!(mem::size_of_val(&a), 16);
111 assert!(is_aligned_to(&a, 16));
113 // raising alignment should not reduce size
114 assert_eq!(mem::align_of::<Align8Many>(), 8);
115 assert_eq!(mem::size_of::<Align8Many>(), 16);
116 let a = Align8Many { a: 1, b: 2, c: 3, d: 4 };
118 assert_eq!(mem::align_of_val(&a), 8);
119 assert_eq!(mem::size_of_val(&a), 16);
120 assert!(is_aligned_to(&a, 8));
123 let a = Align16::new(1);
124 assert_eq!(mem::align_of_val(&a), 16);
125 assert_eq!(mem::size_of_val(&a), 16);
127 assert!(is_aligned_to(&a, 16));
128 assert_eq!(Align16::consume(a), 1);
130 // check const alignment, size and value
131 assert_eq!(mem::align_of_val(&CONST_ALIGN16), 16);
132 assert_eq!(mem::size_of_val(&CONST_ALIGN16), 16);
133 assert_eq!(CONST_ALIGN16.0, 7);
134 assert!(is_aligned_to(&CONST_ALIGN16, 16));
136 // check global static alignment, size and value
137 assert_eq!(mem::align_of_val(&STATIC_ALIGN16), 16);
138 assert_eq!(mem::size_of_val(&STATIC_ALIGN16), 16);
139 assert_eq!(STATIC_ALIGN16.0, 8);
140 assert!(is_aligned_to(&STATIC_ALIGN16, 16));
142 // Note that the size of Nested may change if struct field re-ordering is enabled
143 assert_eq!(mem::align_of::<Nested>(), 16);
144 assert_eq!(mem::size_of::<Nested>(), 48);
145 let a = Nested{ a: 1, b: 2, c: Align16(3), d: 4};
146 assert_eq!(mem::align_of_val(&a), 16);
147 assert_eq!(mem::align_of_val(&a.b), 4);
148 assert_eq!(mem::align_of_val(&a.c), 16);
149 assert_eq!(mem::size_of_val(&a), 48);
150 assert!(is_aligned_to(&a, 16));
151 // check the correct fields are indexed
154 assert_eq!(a.c.0, 3);
157 // enum should be aligned to max alignment
158 assert_eq!(mem::align_of::<Enum>(), 16);
159 assert_eq!(mem::align_of_val(&Enum::B(Align16(0))), 16);
160 let e = Enum::B(Align16(15));
164 assert_eq!(mem::align_of_val(a), 16);
165 assert_eq!(mem::size_of_val(a), 16);
169 assert!(is_aligned_to(&e, 16));
171 // arrays of aligned elements should also be aligned
172 assert_eq!(mem::align_of::<[Align16;2]>(), 16);
173 assert_eq!(mem::size_of::<[Align16;2]>(), 32);
175 let a = [Align16(0), Align16(1)];
176 assert_eq!(mem::align_of_val(&a[0]), 16);
177 assert_eq!(mem::align_of_val(&a[1]), 16);
178 assert!(is_aligned_to(&a, 16));
180 // check heap value is aligned
181 assert_eq!(mem::align_of_val(Box::new(Align16(0)).as_ref()), 16);
183 // check heap array is aligned
184 let a = vec!(Align16(0), Align16(1));
185 assert_eq!(mem::align_of_val(&a[0]), 16);
186 assert_eq!(mem::align_of_val(&a[1]), 16);
188 assert_eq!(mem::align_of::<AlignContainsPacked>(), 16);
189 assert_eq!(mem::size_of::<AlignContainsPacked>(), 16);
190 let a = AlignContainsPacked { a: Packed(1), b: Packed(2) };
191 assert_eq!(mem::align_of_val(&a), 16);
192 assert_eq!(mem::align_of_val(&a.a), 1);
193 assert_eq!(mem::align_of_val(&a.b), 1);
194 assert_eq!(mem::size_of_val(&a), 16);
195 assert!(is_aligned_to(&a, 16));