Skip to content

Commit c84cfa4

Browse files
committed
All init checks go through rustc_const_eval, cleanup
1 parent b361638 commit c84cfa4

File tree

6 files changed

+75
-50
lines changed

6 files changed

+75
-50
lines changed

compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -673,8 +673,11 @@ fn codegen_regular_intrinsic_call<'tcx>(
673673
}
674674

675675
if intrinsic == sym::assert_zero_valid
676-
&& !layout.might_permit_raw_init(
677-
fx,
676+
&& !rustc_const_eval::might_permit_raw_init(
677+
fx.tcx,
678+
source_info.span,
679+
layout,
680+
fx.tcx.sess.opts.debugging_opts.strict_init_checks,
678681
InitKind::Zero) {
679682

680683
with_no_trimmed_paths!({
@@ -688,8 +691,11 @@ fn codegen_regular_intrinsic_call<'tcx>(
688691
}
689692

690693
if intrinsic == sym::assert_uninit_valid
691-
&& !layout.might_permit_raw_init(
692-
fx,
694+
&& !rustc_const_eval::might_permit_raw_init(
695+
fx.tcx,
696+
source_info.span,
697+
layout,
698+
fx.tcx.sess.opts.debugging_opts.strict_init_checks,
693699
InitKind::Uninit) {
694700

695701
with_no_trimmed_paths!({

compiler/rustc_codegen_cranelift/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
extern crate rustc_middle;
99
extern crate rustc_ast;
1010
extern crate rustc_codegen_ssa;
11+
extern crate rustc_const_eval;
1112
extern crate rustc_data_structures;
1213
extern crate rustc_errors;
1314
extern crate rustc_fs_util;

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -549,16 +549,22 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
549549
use AssertIntrinsic::*;
550550
let ty = instance.unwrap().substs.type_at(0);
551551
let layout = bx.layout_of(ty);
552-
let do_panic = match (&intrinsic, strict_validity) {
553-
(Inhabited, _) => layout.abi.is_uninhabited(),
554-
(ZeroValid, true) => {
555-
!rustc_const_eval::is_zero_valid(bx.tcx(), source_info.span, layout)
556-
}
557-
(UninitValid, true) => {
558-
!rustc_const_eval::is_uninit_valid(bx.tcx(), source_info.span, layout)
559-
}
560-
(ZeroValid, false) => !layout.might_permit_raw_init(bx, InitKind::Zero),
561-
(UninitValid, false) => !layout.might_permit_raw_init(bx, InitKind::Uninit),
552+
let do_panic = match &intrinsic {
553+
Inhabited => layout.abi.is_uninhabited(),
554+
ZeroValid => !rustc_const_eval::might_permit_raw_init(
555+
bx.tcx(),
556+
source_info.span,
557+
layout,
558+
strict_validity,
559+
InitKind::Zero,
560+
),
561+
UninitValid => !rustc_const_eval::might_permit_raw_init(
562+
bx.tcx(),
563+
source_info.span,
564+
layout,
565+
strict_validity,
566+
InitKind::Uninit,
567+
),
562568
};
563569
if do_panic {
564570
let msg_str = with_no_visible_paths!({

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -415,11 +415,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
415415
}
416416

417417
if intrinsic_name == sym::assert_zero_valid {
418-
let should_panic = if self.tcx.sess.opts.debugging_opts.strict_init_checks {
419-
!crate::is_zero_valid(*self.tcx, self.cur_span(), layout)
420-
} else {
421-
!layout.might_permit_raw_init(self, InitKind::Zero)
422-
};
418+
let should_panic = !crate::might_permit_raw_init(
419+
*self.tcx,
420+
self.cur_span(),
421+
layout,
422+
self.tcx.sess.opts.debugging_opts.strict_init_checks,
423+
InitKind::Zero,
424+
);
423425

424426
if should_panic {
425427
M::abort(
@@ -433,11 +435,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
433435
}
434436

435437
if intrinsic_name == sym::assert_uninit_valid {
436-
let should_panic = if self.tcx.sess.opts.debugging_opts.strict_init_checks {
437-
!crate::is_uninit_valid(*self.tcx, self.cur_span(), layout)
438-
} else {
439-
!layout.might_permit_raw_init(self, InitKind::Uninit)
440-
};
438+
let should_panic = !crate::might_permit_raw_init(
439+
*self.tcx,
440+
self.cur_span(),
441+
layout,
442+
self.tcx.sess.opts.debugging_opts.strict_init_checks,
443+
InitKind::Uninit,
444+
);
441445

442446
if should_panic {
443447
M::abort(

compiler/rustc_const_eval/src/lib.rs

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -63,38 +63,46 @@ pub fn provide(providers: &mut Providers) {
6363

6464
use crate::const_eval::CompileTimeInterpreter;
6565
use crate::interpret::{InterpCx, MemoryKind, OpTy};
66+
use rustc_middle::ty::layout::LayoutCx;
6667
use rustc_middle::ty::{layout::TyAndLayout, ParamEnv, TyCtxt};
6768
use rustc_session::Limit;
6869
use rustc_span::Span;
70+
use rustc_target::abi::InitKind;
6971

70-
pub fn is_uninit_valid<'tcx>(tcx: TyCtxt<'tcx>, root_span: Span, ty: TyAndLayout<'tcx>) -> bool {
71-
let machine = CompileTimeInterpreter::new(Limit::new(0), false);
72-
let mut cx = InterpCx::new(tcx, root_span, ParamEnv::reveal_all(), machine);
73-
let allocated = cx
74-
.allocate(ty, MemoryKind::Machine(const_eval::MemoryKind::Heap))
75-
.expect("failed to allocate for uninit check");
76-
let ot: OpTy<'_, _> = allocated.into();
77-
cx.validate_operand(&ot).is_ok()
78-
}
79-
80-
pub fn is_zero_valid<'tcx>(tcx: TyCtxt<'tcx>, root_span: Span, ty: TyAndLayout<'tcx>) -> bool {
81-
let machine = CompileTimeInterpreter::new(Limit::new(0), false);
72+
pub fn might_permit_raw_init<'tcx>(
73+
tcx: TyCtxt<'tcx>,
74+
root_span: Span,
75+
ty: TyAndLayout<'tcx>,
76+
strict: bool,
77+
kind: InitKind,
78+
) -> bool {
79+
if strict {
80+
let machine = CompileTimeInterpreter::new(Limit::new(0), false);
8281

83-
let mut cx = InterpCx::new(tcx, root_span, ParamEnv::reveal_all(), machine);
82+
let mut cx = InterpCx::new(tcx, root_span, ParamEnv::reveal_all(), machine);
8483

85-
// We could panic here... Or we could just return "yeah it's valid whatever". Or let
86-
// codegen_panic_intrinsic return an error that halts compilation.
87-
// I'm not exactly sure *when* this can fail. OOM?
88-
let allocated = cx
89-
.allocate(ty, MemoryKind::Machine(const_eval::MemoryKind::Heap))
90-
.expect("failed to allocate for uninit check");
84+
// We could panic here... Or we could just return "yeah it's valid whatever". Or let
85+
// codegen_panic_intrinsic return an error that halts compilation.
86+
// I'm not exactly sure *when* this can fail. OOM?
87+
let allocated = cx
88+
.allocate(ty, MemoryKind::Machine(const_eval::MemoryKind::Heap))
89+
.expect("failed to allocate for uninit check");
9190

92-
// Again, unclear what to do here if it fails.
93-
cx.write_bytes_ptr(allocated.ptr, std::iter::repeat(0_u8).take(ty.layout.size().bytes_usize()))
94-
.expect("failed to write bytes for zero valid check");
91+
if kind == InitKind::Zero {
92+
// Again, unclear what to do here if it fails.
93+
cx.write_bytes_ptr(
94+
allocated.ptr,
95+
std::iter::repeat(0_u8).take(ty.layout.size().bytes_usize()),
96+
)
97+
.expect("failed to write bytes for zero valid check");
98+
}
9599

96-
let ot: OpTy<'_, _> = allocated.into();
100+
let ot: OpTy<'_, _> = allocated.into();
97101

98-
// Assume that if it failed, it's a validation failure.
99-
cx.validate_operand(&ot).is_ok()
102+
// Assume that if it failed, it's a validation failure.
103+
cx.validate_operand(&ot).is_ok()
104+
} else {
105+
let layout_cx = LayoutCx { tcx, param_env: ParamEnv::reveal_all() };
106+
!ty.might_permit_raw_init(&layout_cx, kind)
107+
}
100108
}

compiler/rustc_target/src/abi/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1372,7 +1372,7 @@ pub struct PointeeInfo {
13721372

13731373
/// Used in `might_permit_raw_init` to indicate the kind of initialisation
13741374
/// that is checked to be valid
1375-
#[derive(Copy, Clone, Debug)]
1375+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
13761376
pub enum InitKind {
13771377
Zero,
13781378
Uninit,

0 commit comments

Comments
 (0)