]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_const_eval/src/might_permit_raw_init.rs
fix ICE with extra-const-ub-checks
[rust.git] / compiler / rustc_const_eval / src / might_permit_raw_init.rs
1 use crate::const_eval::CompileTimeInterpreter;
2 use crate::interpret::{InterpCx, MemoryKind, OpTy};
3 use rustc_middle::ty::layout::LayoutCx;
4 use rustc_middle::ty::{layout::TyAndLayout, ParamEnv, TyCtxt};
5 use rustc_session::Limit;
6 use rustc_target::abi::InitKind;
7
8 pub fn might_permit_raw_init<'tcx>(
9     tcx: TyCtxt<'tcx>,
10     ty: TyAndLayout<'tcx>,
11     kind: InitKind,
12 ) -> bool {
13     let strict = tcx.sess.opts.unstable_opts.strict_init_checks;
14
15     if strict {
16         let machine = CompileTimeInterpreter::new(
17             Limit::new(0),
18             /*can_access_statics:*/ false,
19             /*check_alignment:*/ true,
20         );
21
22         let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);
23
24         let allocated = cx
25             .allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))
26             .expect("OOM: failed to allocate for uninit check");
27
28         if kind == InitKind::Zero {
29             cx.write_bytes_ptr(
30                 allocated.ptr,
31                 std::iter::repeat(0_u8).take(ty.layout.size().bytes_usize()),
32             )
33             .expect("failed to write bytes for zero valid check");
34         }
35
36         let ot: OpTy<'_, _> = allocated.into();
37
38         // Assume that if it failed, it's a validation failure.
39         cx.validate_operand(&ot).is_ok()
40     } else {
41         let layout_cx = LayoutCx { tcx, param_env: ParamEnv::reveal_all() };
42         ty.might_permit_raw_init(&layout_cx, kind)
43     }
44 }