diff --git a/tests/ui/layout/aggregate-lang/struct-align.rs b/tests/ui/layout/aggregate-lang/struct-align.rs new file mode 100644 index 0000000000000..f3b88a6d85d3e --- /dev/null +++ b/tests/ui/layout/aggregate-lang/struct-align.rs @@ -0,0 +1,29 @@ +//@ run-pass +//@ reference: layout.aggregate.struct-size-align +//@ edition: 2018 + +#[repr(align(64))] +#[derive(Copy, Clone)] +#[allow(dead_code)] +pub struct Overaligned(u8); + +#[allow(dead_code)] +struct ReprRustStruct { + x: i32, + y: [u32; 4], + z: f32, + a: u128, + b: Overaligned, +} + +fn test_alignment_contains_all_fields() { + assert!(core::mem::align_of::() >= core::mem::align_of::()); + assert!(core::mem::align_of::() >= core::mem::align_of::<[u32; 4]>()); + assert!(core::mem::align_of::() >= core::mem::align_of::()); + assert!(core::mem::align_of::() >= core::mem::align_of::()); + assert!(core::mem::align_of::() >= core::mem::align_of::()); +} + +fn main() { + test_alignment_contains_all_fields(); +} diff --git a/tests/ui/layout/aggregate-lang/struct-offsets.rs b/tests/ui/layout/aggregate-lang/struct-offsets.rs new file mode 100644 index 0000000000000..ca199bdfeb104 --- /dev/null +++ b/tests/ui/layout/aggregate-lang/struct-offsets.rs @@ -0,0 +1,78 @@ +//@ run-pass +//@ reference: layout.aggregate.struct-offsets +//@ edition: 2018 + +#[repr(align(64))] +#[derive(Copy, Clone)] +#[allow(dead_code)] +pub struct Overaligned(u8); + +#[allow(dead_code)] +struct ReprRustStruct { + x: i32, + y: [u32; 4], + z: f32, + a: u128, + b: Overaligned, +} + +macro_rules! span_of { + ($ty:ty , $field:tt) => {{ + let __field = unsafe { ::core::mem::zeroed::<$ty>() }; + + ( + core::mem::offset_of!($ty, $field), + core::mem::offset_of!($ty, $field) + core::mem::size_of_val(&__field.$field), + ) + }}; +} + +fn test_fields_make_sense(a: &(usize, usize)) { + assert!(a.0 <= a.1); +} + +// order is `begin, end` +fn test_non_overlapping(a: &(usize, usize), b: &(usize, usize)) { + assert!((a.1 <= b.0) || (b.1 <= a.0)); +} + +fn test_fields_non_overlapping() { + let fields = [ + span_of!(ReprRustStruct, x), + span_of!(ReprRustStruct, y), + span_of!(ReprRustStruct, z), + span_of!(ReprRustStruct, a), + span_of!(ReprRustStruct, b), + ]; + + test_fields_make_sense(&fields[0]); + test_fields_make_sense(&fields[1]); + test_fields_make_sense(&fields[2]); + test_fields_make_sense(&fields[3]); + test_fields_make_sense(&fields[4]); + + test_non_overlapping(&fields[0], &fields[1]); + test_non_overlapping(&fields[0], &fields[2]); + test_non_overlapping(&fields[0], &fields[3]); + test_non_overlapping(&fields[0], &fields[4]); + test_non_overlapping(&fields[1], &fields[2]); + test_non_overlapping(&fields[2], &fields[3]); + test_non_overlapping(&fields[2], &fields[4]); + test_non_overlapping(&fields[3], &fields[4]); +} + +fn test_fields_aligned() { + assert_eq!((core::mem::offset_of!(ReprRustStruct, x) % (core::mem::align_of::())), 0); + assert_eq!((core::mem::offset_of!(ReprRustStruct, y) % (core::mem::align_of::<[u32; 4]>())), 0); + assert_eq!((core::mem::offset_of!(ReprRustStruct, z) % (core::mem::align_of::())), 0); + assert_eq!((core::mem::offset_of!(ReprRustStruct, a) % (core::mem::align_of::())), 0); + assert_eq!( + (core::mem::offset_of!(ReprRustStruct, b) % (core::mem::align_of::())), + 0 + ); +} + +fn main() { + test_fields_non_overlapping(); + test_fields_aligned(); +} diff --git a/tests/ui/layout/aggregate-lang/struct-size.rs b/tests/ui/layout/aggregate-lang/struct-size.rs new file mode 100644 index 0000000000000..f9fb605c32486 --- /dev/null +++ b/tests/ui/layout/aggregate-lang/struct-size.rs @@ -0,0 +1,50 @@ +//@ run-pass +//@ reference: layout.aggregate.struct-size-align +//@ edition: 2018 + +#[allow(dead_code)] +struct ReprRustStruct { + x: i32, + y: [u32; 4], + z: f32, + a: u128, +} + +fn test_size_contains_all_types() { + assert!( + core::mem::size_of::() + >= (core::mem::size_of::() + + core::mem::size_of::<[u32; 4]>() + + core::mem::size_of::() + + core::mem::size_of::()) + ); +} + +fn test_size_contains_all_fields() { + assert!( + (core::mem::offset_of!(ReprRustStruct, x) + core::mem::size_of::()) + <= core::mem::size_of::() + ); + assert!( + (core::mem::offset_of!(ReprRustStruct, y) + core::mem::size_of::<[u32; 4]>()) + <= core::mem::size_of::() + ); + assert!( + (core::mem::offset_of!(ReprRustStruct, z) + core::mem::size_of::()) + <= core::mem::size_of::() + ); + assert!( + (core::mem::offset_of!(ReprRustStruct, a) + core::mem::size_of::()) + <= core::mem::size_of::() + ); +} + +fn test_size_modulo_align() { + assert_eq!(core::mem::size_of::() % core::mem::align_of::(), 0); +} + +fn main() { + test_size_contains_all_fields(); + test_size_contains_all_types(); + test_size_modulo_align(); +} diff --git a/tests/ui/layout/aggregate-lang/union-align.rs b/tests/ui/layout/aggregate-lang/union-align.rs new file mode 100644 index 0000000000000..03825f1df2137 --- /dev/null +++ b/tests/ui/layout/aggregate-lang/union-align.rs @@ -0,0 +1,29 @@ +//@ run-pass +//@ reference: layout.aggregate.struct-size-align +//@ edition: 2018 + +#[repr(align(64))] +#[derive(Copy, Clone)] +#[allow(dead_code)] +pub struct Overaligned(u8); + +#[allow(dead_code)] +union ReprRustUnion { + x: i32, + y: [u32; 4], + z: f32, + a: u128, + b: Overaligned, +} + +fn test_alignment_contains_all_fields() { + assert!(core::mem::align_of::() >= core::mem::align_of::()); + assert!(core::mem::align_of::() >= core::mem::align_of::<[u32; 4]>()); + assert!(core::mem::align_of::() >= core::mem::align_of::()); + assert!(core::mem::align_of::() >= core::mem::align_of::()); + assert!(core::mem::align_of::() >= core::mem::align_of::()); +} + +fn main() { + test_alignment_contains_all_fields(); +} diff --git a/tests/ui/layout/aggregate-lang/union-offsets.rs b/tests/ui/layout/aggregate-lang/union-offsets.rs new file mode 100644 index 0000000000000..29ab0a9ce5490 --- /dev/null +++ b/tests/ui/layout/aggregate-lang/union-offsets.rs @@ -0,0 +1,32 @@ +//@ run-pass +//@ reference: layout.aggregate.struct-offsets +//@ edition: 2018 + +#[repr(align(64))] +#[derive(Copy, Clone)] +#[allow(dead_code)] +pub struct Overaligned(u8); + +#[allow(dead_code)] +union ReprRustUnion { + x: i32, + y: [u32; 4], + z: f32, + a: u128, + b: Overaligned, +} + +fn test_fields_aligned() { + assert_eq!((core::mem::offset_of!(ReprRustUnion, x) % (core::mem::align_of::())), 0); + assert_eq!((core::mem::offset_of!(ReprRustUnion, y) % (core::mem::align_of::<[u32; 4]>())), 0); + assert_eq!((core::mem::offset_of!(ReprRustUnion, z) % (core::mem::align_of::())), 0); + assert_eq!((core::mem::offset_of!(ReprRustUnion, a) % (core::mem::align_of::())), 0); + assert_eq!( + (core::mem::offset_of!(ReprRustUnion, b) % (core::mem::align_of::())), + 0 + ); +} + +fn main() { + test_fields_aligned(); +} diff --git a/tests/ui/layout/aggregate-lang/union-size.rs b/tests/ui/layout/aggregate-lang/union-size.rs new file mode 100644 index 0000000000000..6d1b51b172db1 --- /dev/null +++ b/tests/ui/layout/aggregate-lang/union-size.rs @@ -0,0 +1,47 @@ +//@ run-pass +//@ reference: layout.aggregate.struct-size-align +//@ edition: 2018 + +#[allow(dead_code)] +union ReprRustUnion { + x: i32, + y: [u32; 4], + z: f32, + a: u128, +} + +fn test_size_contains_each_type() { + assert!(core::mem::size_of::() <= core::mem::size_of::()); + assert!(core::mem::size_of::<[u32; 4]>() <= core::mem::size_of::()); + assert!(core::mem::size_of::() <= core::mem::size_of::()); + assert!(core::mem::size_of::() <= core::mem::size_of::()); +} + +fn test_size_contains_all_fields() { + assert!( + (core::mem::offset_of!(ReprRustUnion, x) + core::mem::size_of::()) + <= core::mem::size_of::() + ); + assert!( + (core::mem::offset_of!(ReprRustUnion, y) + core::mem::size_of::<[u32; 4]>()) + <= core::mem::size_of::() + ); + assert!( + (core::mem::offset_of!(ReprRustUnion, z) + core::mem::size_of::()) + <= core::mem::size_of::() + ); + assert!( + (core::mem::offset_of!(ReprRustUnion, a) + core::mem::size_of::()) + <= core::mem::size_of::() + ); +} + +fn test_size_modulo_align() { + assert_eq!(core::mem::size_of::() % core::mem::align_of::(), 0); +} + +fn main() { + test_size_contains_each_type(); + test_size_contains_all_fields(); + test_size_modulo_align(); +}