Auto merge of #122629 - RalfJung:assert-unsafe-precondition, r=saethlin · rust-lang/rust@2f090c3 (original) (raw)

48 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -2000,7 +2000,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
2000 2000 ConstraintCategory::SizedBound,
2001 2001 );
2002 2002 }
2003 -&Rvalue::NullaryOp(NullOp::UbCheck(_), _) => {}
2003 +&Rvalue::NullaryOp(NullOp::UbChecks, _) => {}
2004 2004
2005 2005 Rvalue::ShallowInitBox(operand, ty) => {
2006 2006 self.check_operand(operand, location);
Original file line number Diff line number Diff line change
@@ -780,7 +780,7 @@ fn codegen_stmt<'tcx>(
780 780 NullOp::OffsetOf(fields) => {
781 781 layout.offset_of_subfield(fx, fields.iter()).bytes()
782 782 }
783 -NullOp::UbCheck(_) => {
783 +NullOp::UbChecks => {
784 784 let val = fx.tcx.sess.opts.debug_assertions;
785 785 let val = CValue::by_val(
786 786 fx.bcx.ins().iconst(types::I8, i64::try_from(val).unwrap()),
Original file line number Diff line number Diff line change
@@ -680,8 +680,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
680 680 let val = layout.offset_of_subfield(bx.cx(), fields.iter()).bytes();
681 681 bx.cx().const_usize(val)
682 682 }
683 - mir::NullOp::UbCheck(_) => {
684 -// In codegen, we want to check for language UB and library UB
683 + mir::NullOp::UbChecks => {
685 684 let val = bx.tcx().sess.opts.debug_assertions;
686 685 bx.cx().const_bool(val)
687 686 }
Original file line number Diff line number Diff line change
@@ -258,17 +258,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
258 258 let val = layout.offset_of_subfield(self, fields.iter()).bytes();
259 259 Scalar::from_target_usize(val, self)
260 260 }
261 - mir::NullOp::UbCheck(kind) => {
262 -// We want to enable checks for library UB, because the interpreter doesn't
263 -// know about those on its own.
264 -// But we want to disable checks for language UB, because the interpreter
265 -// has its own better checks for that.
266 -let should_check = match kind {
267 - mir::UbKind::LibraryUb => self.tcx.sess.opts.debug_assertions,
268 - mir::UbKind::LanguageUb => false,
269 -};
270 -Scalar::from_bool(should_check)
271 -}
261 + mir::NullOp::UbChecks => Scalar::from_bool(self.tcx.sess.opts.debug_assertions),
272 262 };
273 263 self.write_scalar(val, &dest)?;
274 264 }
Original file line number Diff line number Diff line change
@@ -558,7 +558,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
558 558 Rvalue::Cast(_, _, _) => {}
559 559
560 560 Rvalue::NullaryOp(
561 -NullOp::SizeOf | NullOp::AlignOf NullOp::OffsetOf(_) NullOp::UbCheck(_),
561 +NullOp::SizeOf | NullOp::AlignOf NullOp::OffsetOf(_) NullOp::UbChecks,
562 562 _,
563 563 ) => {}
564 564 Rvalue::ShallowInitBox(_, _) => {}
Original file line number Diff line number Diff line change
@@ -1168,7 +1168,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
1168 1168 Rvalue::Repeat(_, _)
1169 1169 | Rvalue::ThreadLocalRef(_)
1170 1170 | Rvalue::AddressOf(_, _)
1171 - | Rvalue::NullaryOp(NullOp::SizeOf NullOp::AlignOf NullOp::UbCheck(_), _)
1171 + | Rvalue::NullaryOp(NullOp::SizeOf NullOp::AlignOf NullOp::UbChecks, _)
1172 1172 | Rvalue::Discriminant(_) => {}
1173 1173 }
1174 1174 self.super_rvalue(rvalue, location);
Original file line number Diff line number Diff line change
@@ -127,8 +127,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
127 127 | sym::variant_count
128 128 | sym::is_val_statically_known
129 129 | sym::ptr_mask
130 - | sym::check_language_ub
131 - | sym::check_library_ub
130 + | sym::ub_checks
132 131 | sym::fadd_algebraic
133 132 | sym::fsub_algebraic
134 133 | sym::fmul_algebraic
@@ -571,7 +570,7 @@ pub fn check_intrinsic_type(
571 570 (0, 0, vec![Ty::new_imm_ptr(tcx, Ty::new_unit(tcx))], tcx.types.usize)
572 571 }
573 572
574 - sym::check_language_ub | sym::check_library_ub => (0, 1, Vec::new(), tcx.types.bool),
573 + sym::ub_checks => (0, 1, Vec::new(), tcx.types.bool),
575 574
576 575 sym::simd_eq
577 576 | sym::simd_ne
Original file line number Diff line number Diff line change
@@ -796,7 +796,7 @@ impl<'tcx> Body<'tcx> {
796 796 }
797 797
798 798 match rvalue {
799 -Rvalue::NullaryOp(NullOp::UbCheck(_), _) => {
799 +Rvalue::NullaryOp(NullOp::UbChecks, _) => {
800 800 Some((tcx.sess.opts.debug_assertions as u128, targets))
801 801 }
802 802 Rvalue::Use(Operand::Constant(constant)) => {
Original file line number Diff line number Diff line change
@@ -944,7 +944,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
944 944 NullOp::SizeOf => write!(fmt, "SizeOf({t})"),
945 945 NullOp::AlignOf => write!(fmt, "AlignOf({t})"),
946 946 NullOp::OffsetOf(fields) => write!(fmt, "OffsetOf({t}, {fields:?})"),
947 -NullOp::UbCheck(kind) => write!(fmt, "UbCheck({kind:?})"),
947 +NullOp::UbChecks => write!(fmt, "UbChecks()"),
948 948 }
949 949 }
950 950 ThreadLocalRef(did) => ty::tls::with(|tcx
Original file line number Diff line number Diff line change
@@ -1367,16 +1367,9 @@ pub enum NullOp<'tcx> {
1367 1367 AlignOf,
1368 1368 /// Returns the offset of a field
1369 1369 OffsetOf(&'tcx List<(VariantIdx, FieldIdx)>),
1370 -/// Returns whether we want to check for library UB or language UB at monomorphization time.
1371 - /// Both kinds of UB evaluate to `true` in codegen, and only library UB evalutes to `true` in
1372 - /// const-eval/Miri, because the interpreter has its own better checks for language UB.
1373 - UbCheck(UbKind),
1374 -}
1375 -
1376 -#[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
1377 -pub enum UbKind {
1378 -LanguageUb,
1379 -LibraryUb,
1370 +/// Returns whether we want to check for UB.
1371 + /// This returns the value of `cfg!(debug_assertions)` at monomorphization time.
1372 + UbChecks,
1380 1373 }
1381 1374
1382 1375 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
Original file line number Diff line number Diff line change
@@ -194,7 +194,7 @@ impl<'tcx> Rvalue<'tcx> {
194 194 Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf NullOp::OffsetOf(..), _) => {
195 195 tcx.types.usize
196 196 }
197 -Rvalue::NullaryOp(NullOp::UbCheck(_), _) => tcx.types.bool,
197 +Rvalue::NullaryOp(NullOp::UbChecks, _) => tcx.types.bool,
198 198 Rvalue::Aggregate(ref ak, ref ops) => match **ak {
199 199 AggregateKind::Array(ty) => Ty::new_array(tcx, ty, ops.len() as u64),
200 200 AggregateKind::Tuple => {
Original file line number Diff line number Diff line change
@@ -433,7 +433,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
433 433 | Rvalue::Discriminant(..)
434 434 | Rvalue::Len(..)
435 435 | Rvalue::NullaryOp(
436 -NullOp::SizeOf | NullOp::AlignOf NullOp::OffsetOf(..) NullOp::UbCheck(_),
436 +NullOp::SizeOf | NullOp::AlignOf NullOp::OffsetOf(..) NullOp::UbChecks,
437 437 _,
438 438 ) => {}
439 439 }
Original file line number Diff line number Diff line change
@@ -487,7 +487,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
487 487 NullOp::OffsetOf(fields) => {
488 488 layout.offset_of_subfield(&self.ecx, fields.iter()).bytes()
489 489 }
490 -NullOp::UbCheck(_) => return None,
490 +NullOp::UbChecks => return None,
491 491 };
492 492 let usize_layout = self.ecx.layout_of(self.tcx.types.usize).unwrap();
493 493 let imm = ImmTy::try_from_uint(val, usize_layout)?;
Original file line number Diff line number Diff line change
@@ -639,7 +639,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
639 639 NullOp::OffsetOf(fields) => {
640 640 op_layout.offset_of_subfield(self, fields.iter()).bytes()
641 641 }
642 -NullOp::UbCheck(_) => return None,
642 +NullOp::UbChecks => return None,
643 643 };
644 644 ImmTy::from_scalar(Scalar::from_target_usize(val, self), layout).into()
645 645 }
Original file line number Diff line number Diff line change
@@ -20,30 +20,13 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
20 20 sym::unreachable => {
21 21 terminator.kind = TerminatorKind::Unreachable;
22 22 }
23 - sym::check_language_ub => {
23 + sym::ub_checks => {
24 24 let target = target.unwrap();
25 25 block.statements.push(Statement {
26 26 source_info: terminator.source_info,
27 27 kind: StatementKind::Assign(Box::new((
28 28 *destination,
29 -Rvalue::NullaryOp(
30 -NullOp::UbCheck(UbKind::LanguageUb),
31 - tcx.types.bool,
32 -),
33 -))),
34 -});
35 - terminator.kind = TerminatorKind::Goto { target };
36 -}
37 - sym::check_library_ub => {
38 -let target = target.unwrap();
39 - block.statements.push(Statement {
40 -source_info: terminator.source_info,
41 -kind: StatementKind::Assign(Box::new((
42 -*destination,
43 -Rvalue::NullaryOp(
44 -NullOp::UbCheck(UbKind::LibraryUb),
45 - tcx.types.bool,
46 -),
29 +Rvalue::NullaryOp(NullOp::UbChecks, tcx.types.bool),
47 30 ))),
48 31 });
49 32 terminator.kind = TerminatorKind::Goto { target };
Original file line number Diff line number Diff line change
@@ -446,7 +446,7 @@ impl<'tcx> Validator<'_, 'tcx> {
446 446 NullOp::SizeOf => {}
447 447 NullOp::AlignOf => {}
448 448 NullOp::OffsetOf(_) => {}
449 -NullOp::UbCheck(_) => {}
449 +NullOp::UbChecks => {}
450 450 },
451 451
452 452 Rvalue::ShallowInitBox(_, _) => return Err(Unpromotable),
Original file line number Diff line number Diff line change
@@ -251,19 +251,13 @@ impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> {
251 251 type T = stable_mir::mir::NullOp;
252 252 fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
253 253 use rustc_middle::mir::NullOp::*;
254 -use rustc_middle::mir::UbKind;
255 254 match self {
256 255 SizeOf => stable_mir::mir::NullOp::SizeOf,
257 256 AlignOf => stable_mir::mir::NullOp::AlignOf,
258 257 OffsetOf(indices) => stable_mir::mir::NullOp::OffsetOf(
259 258 indices.iter().map(|idx
260 259 ),
261 -UbCheck(UbKind::LanguageUb) => {
262 - stable_mir::mir::NullOp::UbCheck(stable_mir::mir::UbKind::LanguageUb)
263 -}
264 -UbCheck(UbKind::LibraryUb) => {
265 - stable_mir::mir::NullOp::UbCheck(stable_mir::mir::UbKind::LibraryUb)
266 -}
260 +UbChecks => stable_mir::mir::NullOp::UbChecks,
267 261 }
268 262 }
269 263 }
Original file line number Diff line number Diff line change
@@ -518,8 +518,6 @@ symbols! {
518 518 cfi,
519 519 cfi_encoding,
520 520 char,
521 - check_language_ub,
522 - check_library_ub,
523 521 client,
524 522 clippy,
525 523 clobber_abi,
@@ -1867,6 +1865,7 @@ symbols! {
1867 1865 u8_legacy_fn_max_value,
1868 1866 u8_legacy_fn_min_value,
1869 1867 u8_legacy_mod,
1868 + ub_checks,
1870 1869 unaligned_volatile_load,
1871 1870 unaligned_volatile_store,
1872 1871 unboxed_closures,
Original file line number Diff line number Diff line change
@@ -621,7 +621,7 @@ impl Rvalue {
621 621 Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf NullOp::OffsetOf(..), _) => {
622 622 Ok(Ty::usize_ty())
623 623 }
624 -Rvalue::NullaryOp(NullOp::UbCheck(_), _) => Ok(Ty::bool_ty()),
624 +Rvalue::NullaryOp(NullOp::UbChecks, _) => Ok(Ty::bool_ty()),
625 625 Rvalue::Aggregate(ak, ops) => match *ak {
626 626 AggregateKind::Array(ty) => Ty::try_new_array(ty, ops.len() as u64),
627 627 AggregateKind::Tuple => Ok(Ty::new_tuple(
@@ -989,13 +989,7 @@ pub enum NullOp {
989 989 /// Returns the offset of a field.
990 990 OffsetOf(Vec<(VariantIdx, FieldIdx)>),
991 991 /// cfg!(debug_assertions), but at codegen time
992 - UbCheck(UbKind),
993 -}
994 -
995 -#[derive(Clone, Debug, Eq, PartialEq)]
996 -pub enum UbKind {
997 -LanguageUb,
998 -LibraryUb,
992 + UbChecks,
999 993 }
1000 994
1001 995 impl Operand {
Original file line number Diff line number Diff line change
@@ -4,9 +4,9 @@ use crate::char::TryFromCharError;
4 4 use crate::convert::TryFrom;
5 5 use crate::error::Error;
6 6 use crate::fmt;
7 -use crate::intrinsics::assert_unsafe_precondition;
8 7 use crate::mem::transmute;
9 8 use crate::str::FromStr;
9 +use crate::ub_checks::assert_unsafe_precondition;
10 10
11 11 /// Converts a `u32` to a `char`. See [`char::from_u32`].
12 12 #[must_use]
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@
4 4 //! Hints may be compile time or runtime.
5 5
6 6 use crate::intrinsics;
7 +use crate::ub_checks;
7 8
8 9 /// Informs the compiler that the site which is calling this function is not
9 10 /// reachable, possibly enabling further optimizations.
@@ -98,7 +99,7 @@ use crate::intrinsics;
98 99 #[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")]
99 100 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
100 101 pub const unsafe fn unreachable_unchecked() -> ! {
101 -intrinsics::assert_unsafe_precondition!(
102 +ub_checks::assert_unsafe_precondition!(
102 103 check_language_ub,
103 104 "hint::unreachable_unchecked must never be reached",
104 105 () => false
@@ -148,7 +149,7 @@ pub const unsafe fn unreachable_unchecked() -> ! {
148 149 pub const unsafe fn assert_unchecked(cond: bool) {
149 150 // SAFETY: The caller promised `cond` is true.
150 151 unsafe {
151 -intrinsics::assert_unsafe_precondition!(
152 +ub_checks::assert_unsafe_precondition!(
152 153 check_language_ub,
153 154 "hint::assert_unchecked must never be called when the condition is false",
154 155 (cond: bool = cond) => cond,