1
Fork 0

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:
Rémy Rakic 2021-06-08 23:47:04 +02:00
parent 47d38752c6
commit d44990367d
3 changed files with 51 additions and 1 deletions

View file

@ -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))
}
}

View 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() {}

View 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