Skip to content

Commit 1e251e3

Browse files
avanhatttedinski
authored andcommitted
Correct check for vtable pointer type (fix Firecracker regression) (rust-lang#279)
* Correct check for vtable pointer type * Comment
1 parent dca74e7 commit 1e251e3

File tree

2 files changed

+15
-12
lines changed

2 files changed

+15
-12
lines changed

compiler/rustc_codegen_llvm/src/gotoc/rvalue.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::cbmc::goto_program::{BuiltinFn, Expr, Location, Stmt, Symbol, Type};
44
use super::cbmc::utils::{aggr_name, BUG_REPORT_URL};
55
use super::cbmc::MachineModel;
66
use super::metadata::*;
7-
use super::typ::{is_dyn_trait_fat_pointer, is_pointer, pointee_type};
7+
use super::typ::{is_pointer, pointee_type};
88
use super::utils::{dynamic_fat_ptr, slice_fat_ptr};
99
use crate::btree_string_map;
1010
use num::bigint::BigInt;
@@ -679,15 +679,18 @@ impl<'tcx> GotocCtx<'tcx> {
679679
) -> Option<Expr> {
680680
// Check if the cast is from a vtable fat pointer to another
681681
// vtable fat pointer (which can happen with auto trait fat pointers)
682-
if is_dyn_trait_fat_pointer(src_mir_type) {
682+
if self.is_vtable_fat_pointer(src_mir_type) {
683683
self.cast_unsized_dyn_trait_to_unsized_dyn_trait(
684684
src_goto_expr.clone(),
685685
src_mir_type,
686686
dst_mir_type,
687687
)
688688
} else {
689-
// Assert that the source is not a pointer or is a thin pointer
690-
assert!(pointee_type(src_mir_type).map_or(true, |p| self.use_thin_pointer(p)));
689+
// Check that the source is either not a pointer, or a thin or a slice pointer
690+
assert!(
691+
pointee_type(src_mir_type)
692+
.map_or(true, |p| self.use_thin_pointer(p) || self.use_slice_fat_pointer(p))
693+
);
691694

692695
// Sized to unsized cast
693696
self.cast_sized_expr_to_unsized_expr(src_goto_expr.clone(), src_mir_type, dst_mir_type)
@@ -923,8 +926,8 @@ impl<'tcx> GotocCtx<'tcx> {
923926
}
924927

925928
// The source destination must be a fat pointers to a dyn trait object
926-
assert!(is_dyn_trait_fat_pointer(src_mir_type));
927-
assert!(is_dyn_trait_fat_pointer(dst_mir_type));
929+
assert!(self.is_vtable_fat_pointer(src_mir_type));
930+
assert!(self.is_vtable_fat_pointer(dst_mir_type));
928931

929932
let dst_mir_dyn_ty = pointee_type(dst_mir_type).unwrap();
930933

@@ -965,7 +968,7 @@ impl<'tcx> GotocCtx<'tcx> {
965968

966969
// The src type cannot be a pointer to a dynamic trait object, otherwise
967970
// we should have called cast_unsized_dyn_trait_to_unsized_dyn_trait
968-
assert!(!is_dyn_trait_fat_pointer(src_mir_type));
971+
assert!(!self.is_vtable_fat_pointer(src_mir_type));
969972

970973
match (src_mir_type.kind(), dst_mir_type.kind()) {
971974
(ty::Ref(..), ty::Ref(..)) => {

compiler/rustc_codegen_llvm/src/gotoc/typ.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,11 +1016,6 @@ pub fn pointee_type(pointer_type: Ty<'tcx>) -> Option<Ty<'tcx>> {
10161016
}
10171017
}
10181018

1019-
/// Check if the mir type already is a vtable fat pointer.
1020-
pub fn is_dyn_trait_fat_pointer(mir_type: Ty<'tcx>) -> bool {
1021-
if let Some(p) = pointee_type(mir_type) { p.is_trait() } else { false }
1022-
}
1023-
10241019
impl<'tcx> GotocCtx<'tcx> {
10251020
/// A pointer to the mir type should be a thin pointer.
10261021
pub fn use_thin_pointer(&self, mir_type: Ty<'tcx>) -> bool {
@@ -1037,4 +1032,9 @@ impl<'tcx> GotocCtx<'tcx> {
10371032
let metadata = mir_type.ptr_metadata_ty(self.tcx);
10381033
return metadata != self.tcx.types.unit && metadata != self.tcx.types.usize;
10391034
}
1035+
1036+
/// Check if the mir type already is a vtable fat pointer.
1037+
pub fn is_vtable_fat_pointer(&self, mir_type: Ty<'tcx>) -> bool {
1038+
pointee_type(mir_type).map_or(false, |p| self.use_vtable_fat_pointer(p))
1039+
}
10401040
}

0 commit comments

Comments
 (0)