Thread a ParamEnv down to might_permit_raw_init

This commit is contained in:
Ben Kimock 2023-01-22 17:06:28 -05:00
parent 662199f125
commit 5bfad5cc85
8 changed files with 45 additions and 22 deletions

View File

@ -21,6 +21,7 @@ macro_rules! intrinsic_args {
pub(crate) use cpuid::codegen_cpuid_call;
pub(crate) use llvm::codegen_llvm_intrinsic_call;
use rustc_middle::ty::layout::HasParamEnv;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::subst::SubstsRef;
use rustc_span::symbol::{kw, sym, Symbol};
@ -659,7 +660,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
return;
}
if intrinsic == sym::assert_zero_valid && !fx.tcx.permits_zero_init(layout) {
if intrinsic == sym::assert_zero_valid
&& !fx.tcx.permits_zero_init(fx.param_env().and(layout))
{
with_no_trimmed_paths!({
crate::base::codegen_panic(
fx,
@ -674,7 +677,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
}
if intrinsic == sym::assert_mem_uninitialized_valid
&& !fx.tcx.permits_uninit_init(layout)
&& !fx.tcx.permits_uninit_init(fx.param_env().and(layout))
{
with_no_trimmed_paths!({
crate::base::codegen_panic(

View File

@ -678,8 +678,8 @@ enum AssertIntrinsic {
let layout = bx.layout_of(ty);
let do_panic = match intrinsic {
Inhabited => layout.abi.is_uninhabited(),
ZeroValid => !bx.tcx().permits_zero_init(layout),
MemUninitializedValid => !bx.tcx().permits_uninit_init(layout),
ZeroValid => !bx.tcx().permits_zero_init(bx.param_env().and(layout)),
MemUninitializedValid => !bx.tcx().permits_uninit_init(bx.param_env().and(layout)),
};
Some(if do_panic {
let msg_str = with_no_visible_paths!({

View File

@ -449,7 +449,7 @@ pub fn emulate_intrinsic(
}
if intrinsic_name == sym::assert_zero_valid {
let should_panic = !self.tcx.permits_zero_init(layout);
let should_panic = !self.tcx.permits_zero_init(self.param_env.and(layout));
if should_panic {
M::abort(
@ -463,7 +463,7 @@ pub fn emulate_intrinsic(
}
if intrinsic_name == sym::assert_mem_uninitialized_valid {
let should_panic = !self.tcx.permits_uninit_init(layout);
let should_panic = !self.tcx.permits_uninit_init(self.param_env.and(layout));
if should_panic {
M::abort(

View File

@ -59,7 +59,12 @@ pub fn provide(providers: &mut Providers) {
let (param_env, value) = param_env_and_value.into_parts();
const_eval::deref_mir_constant(tcx, param_env, value)
};
providers.permits_uninit_init =
|tcx, ty| util::might_permit_raw_init(tcx, ty, InitKind::UninitMitigated0x01Fill);
providers.permits_zero_init = |tcx, ty| util::might_permit_raw_init(tcx, ty, InitKind::Zero);
providers.permits_uninit_init = |tcx, param_env_and_ty| {
let (param_env, ty) = param_env_and_ty.into_parts();
util::might_permit_raw_init(tcx, param_env, ty, InitKind::UninitMitigated0x01Fill)
};
providers.permits_zero_init = |tcx, param_env_and_ty| {
let (param_env, ty) = param_env_and_ty.into_parts();
util::might_permit_raw_init(tcx, param_env, ty, InitKind::Zero)
};
}

View File

@ -20,13 +20,14 @@
/// to the full uninit check).
pub fn might_permit_raw_init<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
ty: TyAndLayout<'tcx>,
kind: InitKind,
) -> bool {
if tcx.sess.opts.unstable_opts.strict_init_checks {
might_permit_raw_init_strict(ty, tcx, kind)
} else {
let layout_cx = LayoutCx { tcx, param_env: ParamEnv::reveal_all() };
let layout_cx = LayoutCx { tcx, param_env };
might_permit_raw_init_lax(ty, &layout_cx, kind)
}
}

View File

@ -2109,12 +2109,12 @@
separate_provide_extern
}
query permits_uninit_init(key: TyAndLayout<'tcx>) -> bool {
desc { "checking to see if `{}` permits being left uninit", key.ty }
query permits_uninit_init(key: ty::ParamEnvAnd<'tcx, TyAndLayout<'tcx>>) -> bool {
desc { "checking to see if `{}` permits being left uninit", key.value.ty }
}
query permits_zero_init(key: TyAndLayout<'tcx>) -> bool {
desc { "checking to see if `{}` permits being left zeroed", key.ty }
query permits_zero_init(key: ty::ParamEnvAnd<'tcx, TyAndLayout<'tcx>>) -> bool {
desc { "checking to see if `{}` permits being left zeroed", key.value.ty }
}
query compare_impl_const(

View File

@ -11,6 +11,7 @@
use rustc_data_structures::functor::IdFunctor;
use rustc_hir::def::Namespace;
use rustc_index::vec::{Idx, IndexVec};
use rustc_target::abi::TyAndLayout;
use std::fmt;
use std::mem::ManuallyDrop;
@ -843,3 +844,9 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow
self.substs.visit_with(visitor)
}
}
impl<'tcx> TypeVisitable<'tcx> for TyAndLayout<'tcx, Ty<'tcx>> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_ty(self.ty)
}
}

View File

@ -6,7 +6,7 @@
BinOp, Body, Constant, ConstantKind, LocalDecls, Operand, Place, ProjectionElem, Rvalue,
SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UnOp,
};
use rustc_middle::ty::{self, layout::TyAndLayout, ParamEnv, SubstsRef, Ty, TyCtxt};
use rustc_middle::ty::{self, layout::TyAndLayout, ParamEnv, ParamEnvAnd, SubstsRef, Ty, TyCtxt};
use rustc_span::symbol::{sym, Symbol};
pub struct InstCombine;
@ -231,7 +231,7 @@ fn combine_intrinsic_assert(
// Check this is a foldable intrinsic before we query the layout of our generic parameter
let Some(assert_panics) = intrinsic_assert_panics(intrinsic_name) else { return; };
let Ok(layout) = self.tcx.layout_of(self.param_env.and(ty)) else { return; };
if assert_panics(self.tcx, layout) {
if assert_panics(self.tcx, self.param_env.and(layout)) {
// If we know the assert panics, indicate to later opts that the call diverges
*target = None;
} else {
@ -243,18 +243,25 @@ fn combine_intrinsic_assert(
fn intrinsic_assert_panics<'tcx>(
intrinsic_name: Symbol,
) -> Option<fn(TyCtxt<'tcx>, TyAndLayout<'tcx>) -> bool> {
fn inhabited_predicate<'tcx>(_tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx>) -> bool {
) -> Option<fn(TyCtxt<'tcx>, ParamEnvAnd<'tcx, TyAndLayout<'tcx>>) -> bool> {
fn inhabited_predicate<'tcx>(
_tcx: TyCtxt<'tcx>,
param_env_and_layout: ParamEnvAnd<'tcx, TyAndLayout<'tcx>>,
) -> bool {
let (_param_env, layout) = param_env_and_layout.into_parts();
layout.abi.is_uninhabited()
}
fn zero_valid_predicate<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx>) -> bool {
!tcx.permits_zero_init(layout)
fn zero_valid_predicate<'tcx>(
tcx: TyCtxt<'tcx>,
param_env_and_layout: ParamEnvAnd<'tcx, TyAndLayout<'tcx>>,
) -> bool {
!tcx.permits_zero_init(param_env_and_layout)
}
fn mem_uninitialized_valid_predicate<'tcx>(
tcx: TyCtxt<'tcx>,
layout: TyAndLayout<'tcx>,
param_env_and_layout: ParamEnvAnd<'tcx, TyAndLayout<'tcx>>,
) -> bool {
!tcx.permits_uninit_init(layout)
!tcx.permits_uninit_init(param_env_and_layout)
}
match intrinsic_name {