From a53c6ee0ba53ba7c4424e8ec1ca08561a880a226 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 5 Sep 2023 09:20:40 +0200 Subject: [PATCH] also ensure that size and alignment are the same --- compiler/rustc_passes/src/abi_test.rs | 10 +- tests/ui/abi/debug.rs | 3 + tests/ui/abi/debug.stderr | 154 +++++++++++++++++++++++++- 3 files changed, 161 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs index 0c707b4ef9c..82392e72677 100644 --- a/compiler/rustc_passes/src/abi_test.rs +++ b/compiler/rustc_passes/src/abi_test.rs @@ -119,9 +119,13 @@ fn test_arg_abi_eq<'tcx>( abi2: &'tcx ArgAbi<'tcx, Ty<'tcx>>, ) -> bool { // Ideally we'd just compare the `mode`, but that is not enough -- for some modes LLVM will look - // at the type. Comparing the `mode` and `layout.abi` should catch basically everything though - // (except for tricky cases around unized types). - abi1.mode.eq_abi(&abi2.mode) && abi1.layout.abi.eq_up_to_validity(&abi2.layout.abi) + // at the type. Comparing the `mode` and `layout.abi` as well as size and alignment should catch + // basically everything though (except for tricky cases around unized types). + abi1.mode.eq_abi(&abi2.mode) + && abi1.layout.abi.eq_up_to_validity(&abi2.layout.abi) + && abi1.layout.size == abi2.layout.size + && abi1.layout.align.abi == abi2.layout.align.abi + && abi1.layout.is_sized() == abi2.layout.is_sized() } fn test_abi_eq<'tcx>(abi1: &'tcx FnAbi<'tcx, Ty<'tcx>>, abi2: &'tcx FnAbi<'tcx, Ty<'tcx>>) -> bool { diff --git a/tests/ui/abi/debug.rs b/tests/ui/abi/debug.rs index d08945ce3c2..9decb41d565 100644 --- a/tests/ui/abi/debug.rs +++ b/tests/ui/abi/debug.rs @@ -39,6 +39,9 @@ type TestAbiEq = (fn(bool), fn(bool)); #[rustc_abi(assert_eq)] type TestAbiNe = (fn(u8), fn(u32)); //~ ERROR: ABIs are not compatible +#[rustc_abi(assert_eq)] +type TestAbiNeLarger = (fn([u8; 32]), fn([u32; 32])); //~ ERROR: ABIs are not compatible + #[rustc_abi(assert_eq)] type TestAbiNeFloat = (fn(f32), fn(u32)); //~ ERROR: ABIs are not compatible diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr index dffeef444f5..0feaf0971d8 100644 --- a/tests/ui/abi/debug.stderr +++ b/tests/ui/abi/debug.stderr @@ -508,6 +508,154 @@ error: ABIs are not compatible LL | type TestAbiNe = (fn(u8), fn(u32)); | ^^^^^^^^^^^^^^ +error: ABIs are not compatible + left ABI = FnAbi { + args: [ + ArgAbi { + layout: TyAndLayout { + ty: [u8; 32], + layout: Layout { + size: Size(32 bytes), + align: AbiAndPrefAlign { + abi: $SOME_ALIGN, + pref: $SOME_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Array { + stride: Size(1 bytes), + count: 32, + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: $SOME_ALIGN, + }, + }, + mode: Indirect { + attrs: ArgAttributes { + regular: NoAlias | NoCapture | NonNull | NoUndef, + arg_ext: None, + pointee_size: Size(32 bytes), + pointee_align: Some( + Align(1 bytes), + ), + }, + extra_attrs: None, + on_stack: false, + }, + }, + ], + ret: ArgAbi { + layout: TyAndLayout { + ty: (), + layout: Layout { + size: Size(0 bytes), + align: AbiAndPrefAlign { + abi: $SOME_ALIGN, + pref: $SOME_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: $SOME_ALIGN, + }, + }, + mode: Ignore, + }, + c_variadic: false, + fixed_count: 1, + conv: Rust, + can_unwind: $SOME_BOOL, + } + right ABI = FnAbi { + args: [ + ArgAbi { + layout: TyAndLayout { + ty: [u32; 32], + layout: Layout { + size: Size(128 bytes), + align: AbiAndPrefAlign { + abi: $SOME_ALIGN, + pref: $SOME_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Array { + stride: Size(4 bytes), + count: 32, + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: $SOME_ALIGN, + }, + }, + mode: Indirect { + attrs: ArgAttributes { + regular: NoAlias | NoCapture | NonNull | NoUndef, + arg_ext: None, + pointee_size: Size(128 bytes), + pointee_align: Some( + Align(4 bytes), + ), + }, + extra_attrs: None, + on_stack: false, + }, + }, + ], + ret: ArgAbi { + layout: TyAndLayout { + ty: (), + layout: Layout { + size: Size(0 bytes), + align: AbiAndPrefAlign { + abi: $SOME_ALIGN, + pref: $SOME_ALIGN, + }, + abi: Aggregate { + sized: true, + }, + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + largest_niche: None, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: $SOME_ALIGN, + }, + }, + mode: Ignore, + }, + c_variadic: false, + fixed_count: 1, + conv: Rust, + can_unwind: $SOME_BOOL, + } + --> $DIR/debug.rs:43:1 + | +LL | type TestAbiNeLarger = (fn([u8; 32]), fn([u32; 32])); + | ^^^^^^^^^^^^^^^^^^^^ + error: ABIs are not compatible left ABI = FnAbi { args: [ @@ -646,7 +794,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:43:1 + --> $DIR/debug.rs:46:1 | LL | type TestAbiNeFloat = (fn(f32), fn(u32)); | ^^^^^^^^^^^^^^^^^^^ @@ -792,10 +940,10 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:47:1 + --> $DIR/debug.rs:50:1 | LL | type TestAbiNeSign = (fn(i32), fn(u32)); | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors