Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 3ca7ba3

Browse files
committed
Auto merge of rust-lang#104862 - saethlin:mir-niche-checks, r=<try>
Check for occupied niches Implementation of rust-lang/compiler-team#624 Crater run has 62 crates that hit the check, 43 of those are published to crates.io. I see a lot of null function pointers and use of `mem::uninitialized` where the 0x1-filling collides with an enum niche. But that is with full niche checks; checking transmute, plus any place where that we Copy, Move, or Inspect. Such checking is definitely too thorough to be on by default because it is 2x compile time overhead. --- During implementation, this ran into llvm/llvm-project#68381 r? `@ghost`
2 parents 6f349cd + 5ac1992 commit 3ca7ba3

File tree

37 files changed

+631
-35
lines changed

37 files changed

+631
-35
lines changed

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,29 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
368368
source_info.span,
369369
);
370370
}
371+
AssertKind::OccupiedNiche {
372+
ref found,
373+
ref start,
374+
ref end,
375+
ref type_name,
376+
ref offset,
377+
ref niche_ty,
378+
} => {
379+
let found = codegen_operand(fx, found).load_scalar(fx);
380+
let start = codegen_operand(fx, start).load_scalar(fx);
381+
let end = codegen_operand(fx, end).load_scalar(fx);
382+
let type_name = fx.anonymous_str(type_name);
383+
let offset = codegen_operand(fx, offset).load_scalar(fx);
384+
let niche_ty = fx.anonymous_str(niche_ty);
385+
let location = fx.get_caller_location(source_info).load_scalar(fx);
386+
387+
codegen_panic_inner(
388+
fx,
389+
rustc_hir::LangItem::PanicOccupiedNiche,
390+
&[found, start, end, type_name, offset, niche_ty, location],
391+
source_info.span,
392+
)
393+
}
371394
_ => {
372395
let msg_str = msg.description();
373396
codegen_panic(fx, msg_str, source_info);

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
624624
// and `#[track_caller]` adds an implicit third argument.
625625
(LangItem::PanicMisalignedPointerDereference, vec![required, found, location])
626626
}
627+
AssertKind::OccupiedNiche { ref found, ref start, ref end } => {
628+
let found = self.codegen_operand(bx, found).immediate();
629+
let start = self.codegen_operand(bx, start).immediate();
630+
let end = self.codegen_operand(bx, end).immediate();
631+
(LangItem::PanicOccupiedNiche, vec![found, start, end, location])
632+
}
627633
_ => {
628634
let msg = bx.const_str(msg.description());
629635
// It's `pub fn panic(expr: &str)`, with the wide reference being passed

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
542542
found: eval_to_int(found)?,
543543
}
544544
}
545+
OccupiedNiche { ref found, ref start, ref end } => OccupiedNiche {
546+
found: eval_to_int(found)?,
547+
start: eval_to_int(start)?,
548+
end: eval_to_int(end)?,
549+
},
545550
};
546551
Err(ConstEvalErrKind::AssertFailure(err).into())
547552
}

compiler/rustc_const_eval/src/interpret/cast.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar};
66
use rustc_middle::mir::CastKind;
77
use rustc_middle::ty::adjustment::PointerCoercion;
88
use rustc_middle::ty::layout::{IntegerExt, LayoutOf, TyAndLayout};
9+
use rustc_middle::ty::print::with_no_trimmed_paths;
910
use rustc_middle::ty::{self, FloatTy, Ty, TypeAndMut};
1011
use rustc_target::abi::Integer;
1112
use rustc_type_ir::TyKind::*;
@@ -147,8 +148,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
147148
if src.layout.size != dest.layout.size {
148149
let src_bytes = src.layout.size.bytes();
149150
let dest_bytes = dest.layout.size.bytes();
150-
let src_ty = format!("{}", src.layout.ty);
151-
let dest_ty = format!("{}", dest.layout.ty);
151+
let src_ty = with_no_trimmed_paths!(format!("{}", src.layout.ty));
152+
let dest_ty = with_no_trimmed_paths!(format!("{}", dest.layout.ty));
152153
throw_ub_custom!(
153154
fluent::const_eval_invalid_transmute,
154155
src_bytes = src_bytes,

compiler/rustc_hir/src/lang_items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ language_item_table! {
234234
ConstPanicFmt, sym::const_panic_fmt, const_panic_fmt, Target::Fn, GenericRequirement::None;
235235
PanicBoundsCheck, sym::panic_bounds_check, panic_bounds_check_fn, Target::Fn, GenericRequirement::Exact(0);
236236
PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, panic_misaligned_pointer_dereference_fn, Target::Fn, GenericRequirement::Exact(0);
237+
PanicOccupiedNiche, sym::panic_occupied_niche, panic_occupied_niche_fn, Target::Fn, GenericRequirement::Exact(0);
237238
PanicInfo, sym::panic_info, panic_info, Target::Struct, GenericRequirement::None;
238239
PanicLocation, sym::panic_location, panic_location, Target::Struct, GenericRequirement::None;
239240
PanicImpl, sym::panic_impl, panic_impl, Target::Fn, GenericRequirement::None;

compiler/rustc_middle/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ middle_assert_divide_by_zero =
1515
middle_assert_misaligned_ptr_deref =
1616
misaligned pointer dereference: address must be a multiple of {$required} but is {$found}
1717
18+
middle_assert_occupied_niche =
19+
occupied niche: {$found} must be in {$start}..={$end}
20+
1821
middle_assert_op_overflow =
1922
attempt to compute `{$left} {$op} {$right}`, which would overflow
2023

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,7 @@ pub enum AssertKind<O> {
886886
ResumedAfterReturn(CoroutineKind),
887887
ResumedAfterPanic(CoroutineKind),
888888
MisalignedPointerDereference { required: O, found: O },
889+
OccupiedNiche { found: O, start: O, end: O },
889890
}
890891

891892
#[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)]

compiler/rustc_middle/src/mir/terminator.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ impl<O> AssertKind<O> {
150150
ResumedAfterReturn(CoroutineKind::Async(_)) => "`async fn` resumed after completion",
151151
ResumedAfterPanic(CoroutineKind::Coroutine) => "coroutine resumed after panicking",
152152
ResumedAfterPanic(CoroutineKind::Async(_)) => "`async fn` resumed after panicking",
153-
BoundsCheck { .. } | MisalignedPointerDereference { .. } => {
153+
BoundsCheck { .. } | MisalignedPointerDereference { .. } | OccupiedNiche { .. } => {
154154
bug!("Unexpected AssertKind")
155155
}
156156
}
@@ -213,6 +213,13 @@ impl<O> AssertKind<O> {
213213
"\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\", {required:?}, {found:?}"
214214
)
215215
}
216+
OccupiedNiche { found, start, end } => {
217+
write!(
218+
f,
219+
"\"occupied niche: {{}} must be in {{}}..={{}}\" {:?} {:?} {:?}",
220+
found, start, end
221+
)
222+
}
216223
_ => write!(f, "\"{}\"", self.description()),
217224
}
218225
}
@@ -243,8 +250,8 @@ impl<O> AssertKind<O> {
243250
ResumedAfterPanic(CoroutineKind::Coroutine) => {
244251
middle_assert_coroutine_resume_after_panic
245252
}
246-
247253
MisalignedPointerDereference { .. } => middle_assert_misaligned_ptr_deref,
254+
OccupiedNiche { .. } => middle_assert_occupied_niche,
248255
}
249256
}
250257

@@ -281,6 +288,11 @@ impl<O> AssertKind<O> {
281288
add!("required", format!("{required:#?}"));
282289
add!("found", format!("{found:#?}"));
283290
}
291+
OccupiedNiche { found, start, end } => {
292+
add!("found", format!("{found:?}"));
293+
add!("start", format!("{start:?}"));
294+
add!("end", format!("{end:?}"));
295+
}
284296
}
285297
}
286298
}

compiler/rustc_middle/src/mir/visit.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,11 @@ macro_rules! make_mir_visitor {
625625
self.visit_operand(required, location);
626626
self.visit_operand(found, location);
627627
}
628+
OccupiedNiche { found, start, end } => {
629+
self.visit_operand(found, location);
630+
self.visit_operand(start, location);
631+
self.visit_operand(end, location);
632+
}
628633
}
629634
}
630635

0 commit comments

Comments
 (0)