3 #![feature(box_syntax)]
9 #[derive(Clone, Copy, Debug)]
12 // Lowering has no effect
16 // Multiple attributes take the max
20 struct AlignMany(i32);
22 // Raising alignment may not alter size.
38 // Nested alignment - use `#[repr(C)]` to suppress field reordering for sizeof test
51 struct AlignContainsPacked {
63 struct AlignContainsPacked4C {
68 // The align limit was originally smaller (2^15).
69 // Check that it works with big numbers.
70 #[repr(align(0x10000))]
75 union UnionContainsAlign {
81 // return aligned type
82 pub fn new(i: i32) -> Align16 {
86 pub fn consume(a: Align16) -> i32 {
91 const CONST_ALIGN16: Align16 = Align16(7);
92 static STATIC_ALIGN16: Align16 = Align16(8);
94 // Check the actual address is aligned
95 fn is_aligned_to<T>(p: &T, align: usize) -> bool {
96 let addr = p as *const T as usize;
97 (addr & (align - 1)) == 0
101 // check alignment and size by type and value
102 assert_eq!(mem::align_of::<Align16>(), 16);
103 assert_eq!(mem::size_of::<Align16>(), 16);
107 assert_eq!(mem::align_of_val(&a), 16);
108 assert_eq!(mem::size_of_val(&a), 16);
110 assert!(is_aligned_to(&a, 16));
112 // lowering should have no effect
113 assert_eq!(mem::align_of::<Align1>(), 4);
114 assert_eq!(mem::size_of::<Align1>(), 4);
117 assert_eq!(mem::align_of_val(&a), 4);
118 assert_eq!(mem::size_of_val(&a), 4);
119 assert!(is_aligned_to(&a, 4));
121 // when multiple attributes are specified the max should be used
122 assert_eq!(mem::align_of::<AlignMany>(), 16);
123 assert_eq!(mem::size_of::<AlignMany>(), 16);
124 let a = AlignMany(7);
126 assert_eq!(mem::align_of_val(&a), 16);
127 assert_eq!(mem::size_of_val(&a), 16);
128 assert!(is_aligned_to(&a, 16));
130 // raising alignment should not reduce size
131 assert_eq!(mem::align_of::<Align8Many>(), 8);
132 assert_eq!(mem::size_of::<Align8Many>(), 16);
133 let a = Align8Many { a: 1, b: 2, c: 3, d: 4 };
135 assert_eq!(mem::align_of_val(&a), 8);
136 assert_eq!(mem::size_of_val(&a), 16);
137 assert!(is_aligned_to(&a, 8));
140 let a = Align16::new(1);
141 assert_eq!(mem::align_of_val(&a), 16);
142 assert_eq!(mem::size_of_val(&a), 16);
144 assert!(is_aligned_to(&a, 16));
145 assert_eq!(Align16::consume(a), 1);
147 // check const alignment, size and value
148 assert_eq!(mem::align_of_val(&CONST_ALIGN16), 16);
149 assert_eq!(mem::size_of_val(&CONST_ALIGN16), 16);
150 assert_eq!(CONST_ALIGN16.0, 7);
151 assert!(is_aligned_to(&CONST_ALIGN16, 16));
153 // check global static alignment, size and value
154 assert_eq!(mem::align_of_val(&STATIC_ALIGN16), 16);
155 assert_eq!(mem::size_of_val(&STATIC_ALIGN16), 16);
156 assert_eq!(STATIC_ALIGN16.0, 8);
157 assert!(is_aligned_to(&STATIC_ALIGN16, 16));
159 // Note that the size of Nested may change if struct field re-ordering is enabled
160 assert_eq!(mem::align_of::<Nested>(), 16);
161 assert_eq!(mem::size_of::<Nested>(), 48);
162 let a = Nested{ a: 1, b: 2, c: Align16(3), d: 4};
163 assert_eq!(mem::align_of_val(&a), 16);
164 assert_eq!(mem::align_of_val(&a.b), 4);
165 assert_eq!(mem::align_of_val(&a.c), 16);
166 assert_eq!(mem::size_of_val(&a), 48);
167 assert!(is_aligned_to(&a, 16));
168 // check the correct fields are indexed
171 assert_eq!(a.c.0, 3);
174 // enum should be aligned to max alignment
175 assert_eq!(mem::align_of::<Enum>(), 16);
176 assert_eq!(mem::align_of_val(&Enum::B(Align16(0))), 16);
177 let e = Enum::B(Align16(15));
181 assert_eq!(mem::align_of_val(a), 16);
182 assert_eq!(mem::size_of_val(a), 16);
186 assert!(is_aligned_to(&e, 16));
188 // check union alignment
189 assert_eq!(mem::align_of::<UnionContainsAlign>(), 16);
190 assert_eq!(mem::size_of::<UnionContainsAlign>(), 16);
191 let u = UnionContainsAlign { a: Align16(10) };
193 assert_eq!(mem::align_of_val(&u.a), 16);
194 assert_eq!(mem::size_of_val(&u.a), 16);
195 assert_eq!(u.a.0, 10);
196 let UnionContainsAlign { a } = u;
200 // arrays of aligned elements should also be aligned
201 assert_eq!(mem::align_of::<[Align16;2]>(), 16);
202 assert_eq!(mem::size_of::<[Align16;2]>(), 32);
204 let a = [Align16(0), Align16(1)];
205 assert_eq!(mem::align_of_val(&a[0]), 16);
206 assert_eq!(mem::align_of_val(&a[1]), 16);
207 assert!(is_aligned_to(&a, 16));
209 // check heap value is aligned
210 assert_eq!(mem::align_of_val(Box::new(Align16(0)).as_ref()), 16);
212 // check heap array is aligned
213 let a = vec!(Align16(0), Align16(1));
214 assert_eq!(mem::align_of_val(&a[0]), 16);
215 assert_eq!(mem::align_of_val(&a[1]), 16);
217 assert_eq!(mem::align_of::<AlignContainsPacked>(), 16);
218 assert_eq!(mem::size_of::<AlignContainsPacked>(), 16);
219 let a = AlignContainsPacked { a: Packed(1), b: Packed(2) };
220 assert_eq!(mem::align_of_val(&a), 16);
221 assert_eq!(mem::align_of_val(&a.a), 1);
222 assert_eq!(mem::align_of_val(&a.b), 1);
223 assert_eq!(mem::size_of_val(&a), 16);
224 assert!(is_aligned_to(&a, 16));
226 assert_eq!(mem::align_of::<AlignContainsPacked4C>(), 16);
227 assert_eq!(mem::size_of::<AlignContainsPacked4C>(), 32);
228 let a = AlignContainsPacked4C { a: Packed4C{ a: 1, b: 2 }, b: 3 };
229 assert_eq!(mem::align_of_val(&a), 16);
230 assert_eq!(mem::align_of_val(&a.a), 4);
231 assert_eq!(mem::align_of_val(&a.b), mem::align_of::<u64>());
232 assert_eq!(mem::size_of_val(&a), 32);
233 assert!(is_aligned_to(&a, 16));
235 let mut large = box AlignLarge {
238 large.stuff[0] = 132;
239 *large.stuff.last_mut().unwrap() = 102;
240 assert_eq!(large.stuff[0], 132);
241 assert_eq!(large.stuff.last(), Some(&102));
242 assert_eq!(mem::align_of::<AlignLarge>(), 0x10000);
243 assert_eq!(mem::align_of_val(&*large), 0x10000);
244 assert!(is_aligned_to(&*large, 0x10000));