8 #[derive(Clone, Copy, Debug)]
11 // Lowering has no effect
15 // Multiple attributes take the max
19 struct AlignMany(i32);
21 // Raising alignment may not alter size.
37 // Nested alignment - use `#[repr(C)]` to suppress field reordering for sizeof test
50 struct AlignContainsPacked {
62 struct AlignContainsPacked4C {
67 // The align limit was originally smaller (2^15).
68 // Check that it works with big numbers.
69 #[repr(align(0x10000))]
74 union UnionContainsAlign {
80 // return aligned type
81 pub fn new(i: i32) -> Align16 {
85 pub fn consume(a: Align16) -> i32 {
90 const CONST_ALIGN16: Align16 = Align16(7);
91 static STATIC_ALIGN16: Align16 = Align16(8);
93 // Check the actual address is aligned
94 fn is_aligned_to<T>(p: &T, align: usize) -> bool {
95 let addr = p as *const T as usize;
96 (addr & (align - 1)) == 0
100 // check alignment and size by type and value
101 assert_eq!(mem::align_of::<Align16>(), 16);
102 assert_eq!(mem::size_of::<Align16>(), 16);
106 assert_eq!(mem::align_of_val(&a), 16);
107 assert_eq!(mem::size_of_val(&a), 16);
109 assert!(is_aligned_to(&a, 16));
111 // lowering should have no effect
112 assert_eq!(mem::align_of::<Align1>(), 4);
113 assert_eq!(mem::size_of::<Align1>(), 4);
116 assert_eq!(mem::align_of_val(&a), 4);
117 assert_eq!(mem::size_of_val(&a), 4);
118 assert!(is_aligned_to(&a, 4));
120 // when multiple attributes are specified the max should be used
121 assert_eq!(mem::align_of::<AlignMany>(), 16);
122 assert_eq!(mem::size_of::<AlignMany>(), 16);
123 let a = AlignMany(7);
125 assert_eq!(mem::align_of_val(&a), 16);
126 assert_eq!(mem::size_of_val(&a), 16);
127 assert!(is_aligned_to(&a, 16));
129 // raising alignment should not reduce size
130 assert_eq!(mem::align_of::<Align8Many>(), 8);
131 assert_eq!(mem::size_of::<Align8Many>(), 16);
132 let a = Align8Many { a: 1, b: 2, c: 3, d: 4 };
134 assert_eq!(mem::align_of_val(&a), 8);
135 assert_eq!(mem::size_of_val(&a), 16);
136 assert!(is_aligned_to(&a, 8));
139 let a = Align16::new(1);
140 assert_eq!(mem::align_of_val(&a), 16);
141 assert_eq!(mem::size_of_val(&a), 16);
143 assert!(is_aligned_to(&a, 16));
144 assert_eq!(Align16::consume(a), 1);
146 // check const alignment, size and value
147 assert_eq!(mem::align_of_val(&CONST_ALIGN16), 16);
148 assert_eq!(mem::size_of_val(&CONST_ALIGN16), 16);
149 assert_eq!(CONST_ALIGN16.0, 7);
150 assert!(is_aligned_to(&CONST_ALIGN16, 16));
152 // check global static alignment, size and value
153 assert_eq!(mem::align_of_val(&STATIC_ALIGN16), 16);
154 assert_eq!(mem::size_of_val(&STATIC_ALIGN16), 16);
155 assert_eq!(STATIC_ALIGN16.0, 8);
156 assert!(is_aligned_to(&STATIC_ALIGN16, 16));
158 // Note that the size of Nested may change if struct field re-ordering is enabled
159 assert_eq!(mem::align_of::<Nested>(), 16);
160 assert_eq!(mem::size_of::<Nested>(), 48);
161 let a = Nested{ a: 1, b: 2, c: Align16(3), d: 4};
162 assert_eq!(mem::align_of_val(&a), 16);
163 assert_eq!(mem::align_of_val(&a.b), 4);
164 assert_eq!(mem::align_of_val(&a.c), 16);
165 assert_eq!(mem::size_of_val(&a), 48);
166 assert!(is_aligned_to(&a, 16));
167 // check the correct fields are indexed
170 assert_eq!(a.c.0, 3);
173 // enum should be aligned to max alignment
174 assert_eq!(mem::align_of::<Enum>(), 16);
175 assert_eq!(mem::align_of_val(&Enum::B(Align16(0))), 16);
176 let e = Enum::B(Align16(15));
180 assert_eq!(mem::align_of_val(a), 16);
181 assert_eq!(mem::size_of_val(a), 16);
185 assert!(is_aligned_to(&e, 16));
187 // check union alignment
188 assert_eq!(mem::align_of::<UnionContainsAlign>(), 16);
189 assert_eq!(mem::size_of::<UnionContainsAlign>(), 16);
190 let u = UnionContainsAlign { a: Align16(10) };
192 assert_eq!(mem::align_of_val(&u.a), 16);
193 assert_eq!(mem::size_of_val(&u.a), 16);
194 assert_eq!(u.a.0, 10);
195 let UnionContainsAlign { a } = u;
199 // arrays of aligned elements should also be aligned
200 assert_eq!(mem::align_of::<[Align16;2]>(), 16);
201 assert_eq!(mem::size_of::<[Align16;2]>(), 32);
203 let a = [Align16(0), Align16(1)];
204 assert_eq!(mem::align_of_val(&a[0]), 16);
205 assert_eq!(mem::align_of_val(&a[1]), 16);
206 assert!(is_aligned_to(&a, 16));
208 // check heap value is aligned
209 assert_eq!(mem::align_of_val(Box::new(Align16(0)).as_ref()), 16);
211 // check heap array is aligned
212 let a = vec!(Align16(0), Align16(1));
213 assert_eq!(mem::align_of_val(&a[0]), 16);
214 assert_eq!(mem::align_of_val(&a[1]), 16);
216 assert_eq!(mem::align_of::<AlignContainsPacked>(), 16);
217 assert_eq!(mem::size_of::<AlignContainsPacked>(), 16);
218 let a = AlignContainsPacked { a: Packed(1), b: Packed(2) };
219 assert_eq!(mem::align_of_val(&a), 16);
220 assert_eq!(mem::align_of_val(&a.a), 1);
221 assert_eq!(mem::align_of_val(&a.b), 1);
222 assert_eq!(mem::size_of_val(&a), 16);
223 assert!(is_aligned_to(&a, 16));
225 assert_eq!(mem::align_of::<AlignContainsPacked4C>(), 16);
226 assert_eq!(mem::size_of::<AlignContainsPacked4C>(), 32);
227 let a = AlignContainsPacked4C { a: Packed4C{ a: 1, b: 2 }, b: 3 };
228 assert_eq!(mem::align_of_val(&a), 16);
229 assert_eq!(mem::align_of_val(&a.a), 4);
230 assert_eq!(mem::align_of_val(&a.b), mem::align_of::<u64>());
231 assert_eq!(mem::size_of_val(&a), 32);
232 assert!(is_aligned_to(&a, 16));
234 let mut large = Box::new(AlignLarge {
237 large.stuff[0] = 132;
238 *large.stuff.last_mut().unwrap() = 102;
239 assert_eq!(large.stuff[0], 132);
240 assert_eq!(large.stuff.last(), Some(&102));
241 assert_eq!(mem::align_of::<AlignLarge>(), 0x10000);
242 assert_eq!(mem::align_of_val(&*large), 0x10000);
243 assert!(is_aligned_to(&*large, 0x10000));