Skip to content

Commit d68dc17

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. r? `@ghost`
2 parents 31ffe48 + 265c955 commit d68dc17

File tree

34 files changed

+747
-15
lines changed

34 files changed

+747
-15
lines changed

compiler/rustc_codegen_cranelift/src/base.rs

+23
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

+29
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,35 @@ 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 {
628+
ref found,
629+
ref start,
630+
ref end,
631+
ref type_name,
632+
ref offset,
633+
ref niche_ty,
634+
} => {
635+
let found = self.codegen_operand(bx, found).immediate();
636+
let start = self.codegen_operand(bx, start).immediate();
637+
let end = self.codegen_operand(bx, end).immediate();
638+
let type_name = bx.const_str(type_name);
639+
let offset = self.codegen_operand(bx, offset).immediate();
640+
let niche_ty = bx.const_str(niche_ty);
641+
(
642+
LangItem::PanicOccupiedNiche,
643+
vec![
644+
found,
645+
start,
646+
end,
647+
type_name.0,
648+
type_name.1,
649+
offset,
650+
niche_ty.0,
651+
niche_ty.1,
652+
location,
653+
],
654+
)
655+
}
627656
_ => {
628657
let msg = bx.const_str(msg.description());
629658
// It's `pub fn panic(expr: &str)`, with the wide reference being passed

compiler/rustc_const_eval/src/const_eval/machine.rs

+15
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,21 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
542542
found: eval_to_int(found)?,
543543
}
544544
}
545+
OccupiedNiche {
546+
ref found,
547+
ref start,
548+
ref end,
549+
ref type_name,
550+
ref offset,
551+
ref niche_ty,
552+
} => OccupiedNiche {
553+
found: eval_to_int(found)?,
554+
start: eval_to_int(start)?,
555+
end: eval_to_int(end)?,
556+
type_name: type_name.clone(),
557+
offset: eval_to_int(offset)?,
558+
niche_ty: niche_ty.clone(),
559+
},
545560
};
546561
Err(ConstEvalErrKind::AssertFailure(err).into())
547562
}

compiler/rustc_hir/src/lang_items.rs

+1
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

+3
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

+1
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, type_name: String, offset: O, niche_ty: String },
889890
}
890891

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

compiler/rustc_middle/src/mir/terminator.rs

+17-2
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, type_name, offset, niche_ty } => {
217+
write!(
218+
f,
219+
"\"occupied niche: {{}} must be in {{}}..={{}} in a {{}} at offset {{}} with type {{}}\" {:?} {:?} {:?} {:?} {:?} {:?}",
220+
found, start, end, type_name, offset, niche_ty
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,14 @@ impl<O> AssertKind<O> {
281288
add!("required", format!("{required:#?}"));
282289
add!("found", format!("{found:#?}"));
283290
}
291+
OccupiedNiche { found, start, end, type_name, offset, niche_ty } => {
292+
add!("found", format!("{found:?}"));
293+
add!("start", format!("{start:?}"));
294+
add!("end", format!("{end:?}"));
295+
add!("type_name", format!("{type_name}"));
296+
add!("offset", format!("{offset:?}"));
297+
add!("niche_ty", format!("{niche_ty}"));
298+
}
284299
}
285300
}
286301
}

compiler/rustc_middle/src/mir/visit.rs

+6
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,12 @@ macro_rules! make_mir_visitor {
625625
self.visit_operand(required, location);
626626
self.visit_operand(found, location);
627627
}
628+
OccupiedNiche { found, start, end, type_name: _, offset, niche_ty: _ } => {
629+
self.visit_operand(found, location);
630+
self.visit_operand(start, location);
631+
self.visit_operand(end, location);
632+
self.visit_operand(offset, location);
633+
}
628634
}
629635
}
630636

0 commit comments

Comments
 (0)