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, |