Skip to content

Commit d449903

Browse files
committed
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
1 parent 47d3875 commit d449903

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

compiler/rustc_mir/src/interpret/traits.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
158158
let size = u64::try_from(self.force_bits(size, pointer_size)?).unwrap();
159159
let align = vtable.read_ptr_sized(pointer_size * 2)?.check_init()?;
160160
let align = u64::try_from(self.force_bits(align, pointer_size)?).unwrap();
161+
let align = Align::from_bytes(align)
162+
.map_err(|e| err_ub_format!("invalid vtable: alignment {}", e))?;
161163

162164
if size >= self.tcx.data_layout.obj_size_bound() {
163165
throw_ub_format!(
164166
"invalid vtable: \
165167
size is bigger than largest supported object"
166168
);
167169
}
168-
Ok((Size::from_bytes(size), Align::from_bytes(align).unwrap()))
170+
Ok((Size::from_bytes(size), align))
169171
}
170172
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// This test contains code with incorrect vtables in a const context:
2+
// - from issue 86132: a trait object with invalid alignment caused an ICE in const eval, and now
3+
// triggers an error
4+
// - a similar test that triggers a previously-untested const UB error: emitted close to the above
5+
// error, it checks the correctness of the size
6+
7+
trait Trait {}
8+
9+
const INVALID_VTABLE_ALIGNMENT: &dyn Trait =
10+
unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
11+
//~^ ERROR any use of this value will cause an error
12+
//~| WARNING this was previously accepted by the compiler
13+
//~| invalid vtable: alignment `1000` is not a power of 2
14+
15+
const INVALID_VTABLE_SIZE: &dyn Trait =
16+
unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) };
17+
//~^ ERROR any use of this value will cause an error
18+
//~| WARNING this was previously accepted by the compiler
19+
//~| invalid vtable: size is bigger than largest supported object
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error: any use of this value will cause an error
2+
--> $DIR/ub-incorrect-vtable.rs:10:14
3+
|
4+
LL | / const INVALID_VTABLE_ALIGNMENT: &dyn Trait =
5+
LL | | unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
6+
| |______________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^__-
7+
| |
8+
| invalid vtable: alignment `1000` is not a power of 2
9+
|
10+
= note: `#[deny(const_err)]` on by default
11+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
12+
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
13+
14+
error: any use of this value will cause an error
15+
--> $DIR/ub-incorrect-vtable.rs:16:14
16+
|
17+
LL | / const INVALID_VTABLE_SIZE: &dyn Trait =
18+
LL | | unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) };
19+
| |______________^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^__-
20+
| |
21+
| invalid vtable: size is bigger than largest supported object
22+
|
23+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
24+
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
25+
26+
error: aborting due to 2 previous errors
27+

0 commit comments

Comments
 (0)