From d44990367d57e40a6ec157174a463818665ac6de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 8 Jun 2021 23:47:04 +0200 Subject: [PATCH] detect incorrect vtable alignment during const eval instead of ICE-ing also add tests for these 2 kinds of errors for size and alignment, as the existing size check wasn't apparently tested --- compiler/rustc_mir/src/interpret/traits.rs | 4 ++- .../consts/const-eval/ub-incorrect-vtable.rs | 21 +++++++++++++++ .../const-eval/ub-incorrect-vtable.stderr | 27 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/consts/const-eval/ub-incorrect-vtable.rs create mode 100644 src/test/ui/consts/const-eval/ub-incorrect-vtable.stderr diff --git a/compiler/rustc_mir/src/interpret/traits.rs b/compiler/rustc_mir/src/interpret/traits.rs index 11f8d388820e8..d0c04b5b414eb 100644 --- a/compiler/rustc_mir/src/interpret/traits.rs +++ b/compiler/rustc_mir/src/interpret/traits.rs @@ -158,6 +158,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let size = u64::try_from(self.force_bits(size, pointer_size)?).unwrap(); let align = vtable.read_ptr_sized(pointer_size * 2)?.check_init()?; let align = u64::try_from(self.force_bits(align, pointer_size)?).unwrap(); + let align = Align::from_bytes(align) + .map_err(|e| err_ub_format!("invalid vtable: alignment {}", e))?; if size >= self.tcx.data_layout.obj_size_bound() { throw_ub_format!( @@ -165,6 +167,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { size is bigger than largest supported object" ); } - Ok((Size::from_bytes(size), Align::from_bytes(align).unwrap())) + Ok((Size::from_bytes(size), align)) } } diff --git a/src/test/ui/consts/const-eval/ub-incorrect-vtable.rs b/src/test/ui/consts/const-eval/ub-incorrect-vtable.rs new file mode 100644 index 0000000000000..0c0e3682de4d6 --- /dev/null +++ b/src/test/ui/consts/const-eval/ub-incorrect-vtable.rs @@ -0,0 +1,21 @@ +// This test contains code with incorrect vtables in a const context: +// - from issue 86132: a trait object with invalid alignment caused an ICE in const eval, and now +// triggers an error +// - a similar test that triggers a previously-untested const UB error: emitted close to the above +// error, it checks the correctness of the size + +trait Trait {} + +const INVALID_VTABLE_ALIGNMENT: &dyn Trait = + unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) }; +//~^ ERROR any use of this value will cause an error +//~| WARNING this was previously accepted by the compiler +//~| invalid vtable: alignment `1000` is not a power of 2 + +const INVALID_VTABLE_SIZE: &dyn Trait = + unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) }; +//~^ ERROR any use of this value will cause an error +//~| WARNING this was previously accepted by the compiler +//~| invalid vtable: size is bigger than largest supported object + +fn main() {} diff --git a/src/test/ui/consts/const-eval/ub-incorrect-vtable.stderr b/src/test/ui/consts/const-eval/ub-incorrect-vtable.stderr new file mode 100644 index 0000000000000..c937d039d381e --- /dev/null +++ b/src/test/ui/consts/const-eval/ub-incorrect-vtable.stderr @@ -0,0 +1,27 @@ +error: any use of this value will cause an error + --> $DIR/ub-incorrect-vtable.rs:10:14 + | +LL | / const INVALID_VTABLE_ALIGNMENT: &dyn Trait = +LL | | unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) }; + | |______________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^__- + | | + | invalid vtable: alignment `1000` is not a power of 2 + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +error: any use of this value will cause an error + --> $DIR/ub-incorrect-vtable.rs:16:14 + | +LL | / const INVALID_VTABLE_SIZE: &dyn Trait = +LL | | unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) }; + | |______________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^__- + | | + | invalid vtable: size is bigger than largest supported object + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +error: aborting due to 2 previous errors +