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
This commit is contained in:
parent
47d38752c6
commit
d44990367d
3 changed files with 51 additions and 1 deletions
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
21
src/test/ui/consts/const-eval/ub-incorrect-vtable.rs
Normal file
21
src/test/ui/consts/const-eval/ub-incorrect-vtable.rs
Normal file
|
@ -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() {}
|
27
src/test/ui/consts/const-eval/ub-incorrect-vtable.stderr
Normal file
27
src/test/ui/consts/const-eval/ub-incorrect-vtable.stderr
Normal file
|
@ -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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/71800>
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue