Skip to content

Commit 4091821

Browse files
committed
Auto merge of rust-lang#129498 - saethlin:ptr-read-write-precondition, r=<try>
Try enabling precondition checks on ptr::{read,write} The overhead here is probably too much, but let's have the measurement anyway. This will fail at least one codegen test. r? `@ghost`
2 parents 1f12b9b + 3b756c6 commit 4091821

File tree

5 files changed

+24
-7
lines changed

5 files changed

+24
-7
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

+4
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
681681
rustc_nounwind, Normal, template!(Word), WarnFollowing,
682682
EncodeCrossCrate::No, IMPL_DETAIL
683683
),
684+
rustc_attr!(
685+
rustc_no_ubchecks, Normal, template!(Word), WarnFollowing,
686+
EncodeCrossCrate::No, IMPL_DETAIL
687+
),
684688
rustc_attr!(
685689
rustc_reallocator, Normal, template!(Word), WarnFollowing,
686690
EncodeCrossCrate::No, IMPL_DETAIL

compiler/rustc_mir_transform/src/instsimplify.rs

+18-5
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,27 @@ impl<'tcx> MirPass<'tcx> for InstSimplify {
3737
}
3838

3939
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
40+
let def_id = body.source.def_id();
4041
let ctx = InstSimplifyContext {
4142
tcx,
4243
local_decls: &body.local_decls,
43-
param_env: tcx.param_env_reveal_all_normalized(body.source.def_id()),
44+
param_env: tcx.param_env_reveal_all_normalized(def_id),
4445
};
4546
let preserve_ub_checks =
4647
attr::contains_name(tcx.hir().krate_attrs(), sym::rustc_preserve_ub_checks);
48+
let remove_ub_checks = tcx.has_attr(def_id, sym::rustc_no_ubchecks);
4749
for block in body.basic_blocks.as_mut() {
4850
for statement in block.statements.iter_mut() {
4951
match statement.kind {
5052
StatementKind::Assign(box (_place, ref mut rvalue)) => {
51-
if !preserve_ub_checks {
52-
ctx.simplify_ub_check(&statement.source_info, rvalue);
53+
if remove_ub_checks {
54+
ctx.simplify_ub_check(&statement.source_info, rvalue, false);
55+
} else if !preserve_ub_checks {
56+
ctx.simplify_ub_check(
57+
&statement.source_info,
58+
rvalue,
59+
tcx.sess.ub_checks(),
60+
);
5361
}
5462
ctx.simplify_bool_cmp(&statement.source_info, rvalue);
5563
ctx.simplify_ref_deref(&statement.source_info, rvalue);
@@ -199,9 +207,14 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
199207
}
200208
}
201209

202-
fn simplify_ub_check(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
210+
fn simplify_ub_check(
211+
&self,
212+
source_info: &SourceInfo,
213+
rvalue: &mut Rvalue<'tcx>,
214+
ub_checks: bool,
215+
) {
203216
if let Rvalue::NullaryOp(NullOp::UbChecks, _) = *rvalue {
204-
let const_ = Const::from_bool(self.tcx, self.tcx.sess.ub_checks());
217+
let const_ = Const::from_bool(self.tcx, ub_checks);
205218
let constant = ConstOperand { span: source_info.span, const_, user_ty: None };
206219
*rvalue = Rvalue::Use(Operand::Constant(Box::new(constant)));
207220
}

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1655,6 +1655,7 @@ symbols! {
16551655
rustc_never_returns_null_ptr,
16561656
rustc_never_type_options,
16571657
rustc_no_mir_inline,
1658+
rustc_no_ubchecks,
16581659
rustc_nonnull_optimization_guaranteed,
16591660
rustc_nounwind,
16601661
rustc_object_lifetime_default,

library/core/src/mem/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,7 @@ pub fn take<T: Default>(dest: &mut T) -> T {
859859
#[must_use = "if you don't need the old value, you can just assign the new value directly"]
860860
#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
861861
#[cfg_attr(not(test), rustc_diagnostic_item = "mem_replace")]
862+
#[cfg_attr(not(bootstrap), rustc_no_ubchecks)]
862863
pub const fn replace<T>(dest: &mut T, src: T) -> T {
863864
// It may be tempting to use `swap` to avoid `unsafe` here. Don't!
864865
// The compiler optimizes the implementation below to two `memcpy`s

library/core/src/ptr/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1425,7 +1425,6 @@ pub const unsafe fn read<T>(src: *const T) -> T {
14251425

14261426
// SAFETY: the caller must guarantee that `src` is valid for reads.
14271427
unsafe {
1428-
#[cfg(debug_assertions)] // Too expensive to always enable (for now?)
14291428
ub_checks::assert_unsafe_precondition!(
14301429
check_language_ub,
14311430
"ptr::read requires that the pointer argument is aligned and non-null",
@@ -1634,7 +1633,6 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
16341633
// `dst` cannot overlap `src` because the caller has mutable access
16351634
// to `dst` while `src` is owned by this function.
16361635
unsafe {
1637-
#[cfg(debug_assertions)] // Too expensive to always enable (for now?)
16381636
ub_checks::assert_unsafe_precondition!(
16391637
check_language_ub,
16401638
"ptr::write requires that the pointer argument is aligned and non-null",

0 commit comments

Comments
 (0)