From 3d67fd4cf4dfcdfb93e880a09ed7d41d95170226 Mon Sep 17 00:00:00 2001 From: Connor Horman Date: Fri, 22 Nov 2024 19:32:02 -0500 Subject: [PATCH 1/2] Add language tests for aggregate types --- .../ui/layout/aggregate-lang/struct-align.rs | 31 +++++++ .../layout/aggregate-lang/struct-offsets.rs | 93 +++++++++++++++++++ tests/ui/layout/aggregate-lang/struct-size.rs | 57 ++++++++++++ tests/ui/layout/aggregate-lang/union-align.rs | 31 +++++++ .../ui/layout/aggregate-lang/union-offsets.rs | 46 +++++++++ tests/ui/layout/aggregate-lang/union-size.rs | 54 +++++++++++ 6 files changed, 312 insertions(+) create mode 100644 tests/ui/layout/aggregate-lang/struct-align.rs create mode 100644 tests/ui/layout/aggregate-lang/struct-offsets.rs create mode 100644 tests/ui/layout/aggregate-lang/struct-size.rs create mode 100644 tests/ui/layout/aggregate-lang/union-align.rs create mode 100644 tests/ui/layout/aggregate-lang/union-offsets.rs create mode 100644 tests/ui/layout/aggregate-lang/union-size.rs 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..931d686798daa --- /dev/null +++ b/tests/ui/layout/aggregate-lang/struct-align.rs @@ -0,0 +1,31 @@ +//@ 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, +} + +#[cfg_attr(test, test)] +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::()); +} + +#[cfg(not(test))] +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..62e16e6d8434e --- /dev/null +++ b/tests/ui/layout/aggregate-lang/struct-offsets.rs @@ -0,0 +1,93 @@ +//@ 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)); +} + +#[cfg_attr(test, test)] +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]); +} + +#[cfg_attr(test, test)] +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 + ); +} + +#[cfg(not(test))] +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..3d93a8dca3487 --- /dev/null +++ b/tests/ui/layout/aggregate-lang/struct-size.rs @@ -0,0 +1,57 @@ +//@ run-pass +//@ reference: layout.aggregate.struct-size-align +//@ edition: 2018 + +#[allow(dead_code)] +struct ReprRustStruct { + x: i32, + y: [u32; 4], + z: f32, + a: u128, +} + +#[cfg_attr(test, test)] +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::()) + ); +} + +#[cfg_attr(test, test)] +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::() + ); +} + +#[cfg_attr(test, test)] +fn test_size_modulo_align() { + assert_eq!( + core::mem::size_of::() % core::mem::align_of::(), + 0 + ); +} + +#[cfg(not(test))] +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..a37d94abfa832 --- /dev/null +++ b/tests/ui/layout/aggregate-lang/union-align.rs @@ -0,0 +1,31 @@ +//@ 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, +} + +#[cfg_attr(test, test)] +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::()); +} + +#[cfg(not(test))] +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..2a2f7d9c790b7 --- /dev/null +++ b/tests/ui/layout/aggregate-lang/union-offsets.rs @@ -0,0 +1,46 @@ +//@ 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, +} + +#[cfg_attr(test, test)] +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 + ); +} + +#[cfg(not(test))] +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..f82412f50899a --- /dev/null +++ b/tests/ui/layout/aggregate-lang/union-size.rs @@ -0,0 +1,54 @@ +//@ run-pass +//@ reference: layout.aggregate.struct-size-align +//@ edition: 2018 + +#[allow(dead_code)] +union ReprRustUnion { + x: i32, + y: [u32; 4], + z: f32, + a: u128, +} + +#[cfg_attr(test, test)] +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::()); +} + +#[cfg_attr(test, test)] +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::() + ); +} + +#[cfg_attr(test, test)] +fn test_size_modulo_align() { + assert_eq!( + core::mem::size_of::() % core::mem::align_of::(), + 0 + ); +} + +#[cfg(not(test))] +fn main() { + test_size_contains_each_type(); + test_size_contains_all_fields(); + test_size_modulo_align(); +} From 8578ccc7add524147a8c524a336b050fb7647087 Mon Sep 17 00:00:00 2001 From: Connor Horman Date: Fri, 22 Nov 2024 21:07:02 -0500 Subject: [PATCH 2/2] Remove `#[cfg(test)]` related stubs --- .../ui/layout/aggregate-lang/struct-align.rs | 2 -- .../layout/aggregate-lang/struct-offsets.rs | 23 ++++--------------- tests/ui/layout/aggregate-lang/struct-size.rs | 9 +------- tests/ui/layout/aggregate-lang/union-align.rs | 2 -- .../ui/layout/aggregate-lang/union-offsets.rs | 22 ++++-------------- tests/ui/layout/aggregate-lang/union-size.rs | 9 +------- 6 files changed, 10 insertions(+), 57 deletions(-) diff --git a/tests/ui/layout/aggregate-lang/struct-align.rs b/tests/ui/layout/aggregate-lang/struct-align.rs index 931d686798daa..f3b88a6d85d3e 100644 --- a/tests/ui/layout/aggregate-lang/struct-align.rs +++ b/tests/ui/layout/aggregate-lang/struct-align.rs @@ -16,7 +16,6 @@ struct ReprRustStruct { b: Overaligned, } -#[cfg_attr(test, test)] 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]>()); @@ -25,7 +24,6 @@ fn test_alignment_contains_all_fields() { assert!(core::mem::align_of::() >= core::mem::align_of::()); } -#[cfg(not(test))] 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 index 62e16e6d8434e..ca199bdfeb104 100644 --- a/tests/ui/layout/aggregate-lang/struct-offsets.rs +++ b/tests/ui/layout/aggregate-lang/struct-offsets.rs @@ -36,7 +36,6 @@ fn test_non_overlapping(a: &(usize, usize), b: &(usize, usize)) { assert!((a.1 <= b.0) || (b.1 <= a.0)); } -#[cfg_attr(test, test)] fn test_fields_non_overlapping() { let fields = [ span_of!(ReprRustStruct, x), @@ -62,31 +61,17 @@ fn test_fields_non_overlapping() { test_non_overlapping(&fields[3], &fields[4]); } -#[cfg_attr(test, test)] 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, 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 ); } -#[cfg(not(test))] 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 index 3d93a8dca3487..f9fb605c32486 100644 --- a/tests/ui/layout/aggregate-lang/struct-size.rs +++ b/tests/ui/layout/aggregate-lang/struct-size.rs @@ -10,7 +10,6 @@ struct ReprRustStruct { a: u128, } -#[cfg_attr(test, test)] fn test_size_contains_all_types() { assert!( core::mem::size_of::() @@ -21,7 +20,6 @@ fn test_size_contains_all_types() { ); } -#[cfg_attr(test, test)] fn test_size_contains_all_fields() { assert!( (core::mem::offset_of!(ReprRustStruct, x) + core::mem::size_of::()) @@ -41,15 +39,10 @@ fn test_size_contains_all_fields() { ); } -#[cfg_attr(test, test)] fn test_size_modulo_align() { - assert_eq!( - core::mem::size_of::() % core::mem::align_of::(), - 0 - ); + assert_eq!(core::mem::size_of::() % core::mem::align_of::(), 0); } -#[cfg(not(test))] fn main() { test_size_contains_all_fields(); test_size_contains_all_types(); diff --git a/tests/ui/layout/aggregate-lang/union-align.rs b/tests/ui/layout/aggregate-lang/union-align.rs index a37d94abfa832..03825f1df2137 100644 --- a/tests/ui/layout/aggregate-lang/union-align.rs +++ b/tests/ui/layout/aggregate-lang/union-align.rs @@ -16,7 +16,6 @@ union ReprRustUnion { b: Overaligned, } -#[cfg_attr(test, test)] 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]>()); @@ -25,7 +24,6 @@ fn test_alignment_contains_all_fields() { assert!(core::mem::align_of::() >= core::mem::align_of::()); } -#[cfg(not(test))] 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 index 2a2f7d9c790b7..29ab0a9ce5490 100644 --- a/tests/ui/layout/aggregate-lang/union-offsets.rs +++ b/tests/ui/layout/aggregate-lang/union-offsets.rs @@ -16,31 +16,17 @@ union ReprRustUnion { b: Overaligned, } -#[cfg_attr(test, test)] 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, 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 ); } -#[cfg(not(test))] 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 index f82412f50899a..6d1b51b172db1 100644 --- a/tests/ui/layout/aggregate-lang/union-size.rs +++ b/tests/ui/layout/aggregate-lang/union-size.rs @@ -10,7 +10,6 @@ union ReprRustUnion { a: u128, } -#[cfg_attr(test, test)] 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::()); @@ -18,7 +17,6 @@ fn test_size_contains_each_type() { assert!(core::mem::size_of::() <= core::mem::size_of::()); } -#[cfg_attr(test, test)] fn test_size_contains_all_fields() { assert!( (core::mem::offset_of!(ReprRustUnion, x) + core::mem::size_of::()) @@ -38,15 +36,10 @@ fn test_size_contains_all_fields() { ); } -#[cfg_attr(test, test)] fn test_size_modulo_align() { - assert_eq!( - core::mem::size_of::() % core::mem::align_of::(), - 0 - ); + assert_eq!(core::mem::size_of::() % core::mem::align_of::(), 0); } -#[cfg(not(test))] fn main() { test_size_contains_each_type(); test_size_contains_all_fields();