Skip to content

Commit d9d92ed

Browse files
committed
Move alignment failure error reporting to machine
1 parent d66824d commit d9d92ed

File tree

6 files changed

+78
-44
lines changed

6 files changed

+78
-44
lines changed

compiler/rustc_const_eval/src/const_eval/machine.rs

+37-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use rustc_hir::def::DefKind;
2-
use rustc_hir::LangItem;
2+
use rustc_hir::{LangItem, CRATE_HIR_ID};
33
use rustc_middle::mir;
4-
use rustc_middle::mir::interpret::PointerArithmetic;
4+
use rustc_middle::mir::interpret::{PointerArithmetic, UndefinedBehaviorInfo};
55
use rustc_middle::ty::layout::FnAbiOf;
66
use rustc_middle::ty::{self, Ty, TyCtxt};
7+
use rustc_session::lint::builtin::INVALID_ALIGNMENT;
78
use std::borrow::Borrow;
89
use std::hash::Hash;
910
use std::ops::ControlFlow;
@@ -338,6 +339,40 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
338339
ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks
339340
}
340341

342+
fn alignment_check_failed(
343+
ecx: &InterpCx<'mir, 'tcx, Self>,
344+
has: Align,
345+
required: Align,
346+
check: CheckAlignment,
347+
) -> InterpResult<'tcx, ()> {
348+
match check {
349+
CheckAlignment::Error => {
350+
throw_ub!(AlignmentCheckFailed { has, required })
351+
}
352+
CheckAlignment::No => span_bug!(
353+
ecx.cur_span(),
354+
"`alignment_check_failed` called when no alignment check requested"
355+
),
356+
CheckAlignment::FutureIncompat => ecx.tcx.struct_span_lint_hir(
357+
INVALID_ALIGNMENT,
358+
ecx.stack().iter().find_map(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID),
359+
ecx.cur_span(),
360+
UndefinedBehaviorInfo::AlignmentCheckFailed { has, required }.to_string(),
361+
|db| {
362+
let mut stacktrace = ecx.generate_stacktrace();
363+
// Filter out `requires_caller_location` frames.
364+
stacktrace
365+
.retain(|frame| !frame.instance.def.requires_caller_location(*ecx.tcx));
366+
for frame in stacktrace {
367+
db.span_label(frame.span, format!("inside `{}`", frame.instance));
368+
}
369+
db
370+
},
371+
),
372+
}
373+
Ok(())
374+
}
375+
341376
fn load_mir(
342377
ecx: &InterpCx<'mir, 'tcx, Self>,
343378
instance: ty::InstanceDef<'tcx>,

compiler/rustc_const_eval/src/interpret/machine.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
1010
use rustc_middle::mir;
1111
use rustc_middle::ty::{self, Ty, TyCtxt};
1212
use rustc_span::def_id::DefId;
13-
use rustc_target::abi::Size;
13+
use rustc_target::abi::{Align, Size};
1414
use rustc_target::spec::abi::Abi as CallAbi;
1515

1616
use crate::const_eval::CheckAlignment;
@@ -132,6 +132,13 @@ pub trait Machine<'mir, 'tcx>: Sized {
132132
/// If this returns true, Provenance::OFFSET_IS_ADDR must be true.
133133
fn use_addr_for_alignment_check(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
134134

135+
fn alignment_check_failed(
136+
ecx: &InterpCx<'mir, 'tcx, Self>,
137+
has: Align,
138+
required: Align,
139+
check: CheckAlignment,
140+
) -> InterpResult<'tcx, ()>;
141+
135142
/// Whether to enforce the validity invariant
136143
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
137144

compiler/rustc_const_eval/src/interpret/memory.rs

+2-39
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,8 @@ use std::ptr;
1414

1515
use rustc_ast::Mutability;
1616
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
17-
use rustc_hir::CRATE_HIR_ID;
1817
use rustc_middle::mir::display_allocation;
19-
use rustc_middle::mir::interpret::UndefinedBehaviorInfo;
2018
use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
21-
use rustc_session::lint::builtin::INVALID_ALIGNMENT;
2219
use rustc_target::abi::{Align, HasDataLayout, Size};
2320

2421
use crate::const_eval::CheckAlignment;
@@ -448,7 +445,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
448445
} else {
449446
// Check allocation alignment and offset alignment.
450447
if alloc_align.bytes() < align.bytes() {
451-
self.alignment_check_failed(alloc_align, align, check)?;
448+
M::alignment_check_failed(self, alloc_align, align, check)?;
452449
}
453450
self.check_offset_align(offset.bytes(), align, check)?;
454451
}
@@ -472,43 +469,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
472469
} else {
473470
// The biggest power of two through which `offset` is divisible.
474471
let offset_pow2 = 1 << offset.trailing_zeros();
475-
self.alignment_check_failed(Align::from_bytes(offset_pow2).unwrap(), align, check)
472+
M::alignment_check_failed(self, Align::from_bytes(offset_pow2).unwrap(), align, check)
476473
}
477474
}
478-
479-
fn alignment_check_failed(
480-
&self,
481-
has: Align,
482-
required: Align,
483-
check: CheckAlignment,
484-
) -> InterpResult<'tcx, ()> {
485-
match check {
486-
CheckAlignment::Error => {
487-
throw_ub!(AlignmentCheckFailed { has, required })
488-
}
489-
CheckAlignment::No => span_bug!(
490-
self.cur_span(),
491-
"`alignment_check_failed` called when no alignment check requested"
492-
),
493-
CheckAlignment::FutureIncompat => self.tcx.struct_span_lint_hir(
494-
INVALID_ALIGNMENT,
495-
self.stack().iter().find_map(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID),
496-
self.cur_span(),
497-
UndefinedBehaviorInfo::AlignmentCheckFailed { has, required }.to_string(),
498-
|db| {
499-
let mut stacktrace = self.generate_stacktrace();
500-
// Filter out `requires_caller_location` frames.
501-
stacktrace
502-
.retain(|frame| !frame.instance.def.requires_caller_location(*self.tcx));
503-
for frame in stacktrace {
504-
db.span_label(frame.span, format!("inside `{}`", frame.instance));
505-
}
506-
db
507-
},
508-
),
509-
}
510-
Ok(())
511-
}
512475
}
513476

514477
/// Allocation accessors

compiler/rustc_mir_transform/src/const_prop.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayo
2323
use rustc_middle::ty::InternalSubsts;
2424
use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable};
2525
use rustc_span::{def_id::DefId, Span};
26-
use rustc_target::abi::{self, HasDataLayout, Size, TargetDataLayout};
26+
use rustc_target::abi::{self, Align, HasDataLayout, Size, TargetDataLayout};
2727
use rustc_target::spec::abi::Abi as CallAbi;
2828
use rustc_trait_selection::traits;
2929

@@ -197,6 +197,17 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
197197
fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
198198
false // for now, we don't enforce validity
199199
}
200+
fn alignment_check_failed(
201+
ecx: &InterpCx<'mir, 'tcx, Self>,
202+
_has: Align,
203+
_required: Align,
204+
_check: CheckAlignment,
205+
) -> InterpResult<'tcx, ()> {
206+
span_bug!(
207+
ecx.cur_span(),
208+
"`alignment_check_failed` called when no alignment check requested"
209+
)
210+
}
200211

201212
fn load_mir(
202213
_ecx: &InterpCx<'mir, 'tcx, Self>,

compiler/rustc_mir_transform/src/dataflow_const_prop.rs

+9
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
1111
use rustc_mir_dataflow::value_analysis::{Map, State, TrackElem, ValueAnalysis, ValueOrPlace};
1212
use rustc_mir_dataflow::{lattice::FlatSet, Analysis, ResultsVisitor, SwitchIntEdgeEffects};
1313
use rustc_span::DUMMY_SP;
14+
use rustc_target::abi::Align;
1415

1516
use crate::MirPass;
1617

@@ -456,6 +457,14 @@ impl<'mir, 'tcx> rustc_const_eval::interpret::Machine<'mir, 'tcx> for DummyMachi
456457
fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
457458
unimplemented!()
458459
}
460+
fn alignment_check_failed(
461+
_ecx: &InterpCx<'mir, 'tcx, Self>,
462+
_has: Align,
463+
_required: Align,
464+
_check: CheckAlignment,
465+
) -> interpret::InterpResult<'tcx, ()> {
466+
unimplemented!()
467+
}
459468

460469
fn find_mir_or_eval_fn(
461470
_ecx: &mut InterpCx<'mir, 'tcx, Self>,

src/tools/miri/src/machine.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc_middle::{
2222
};
2323
use rustc_span::def_id::{CrateNum, DefId};
2424
use rustc_span::Symbol;
25-
use rustc_target::abi::Size;
25+
use rustc_target::abi::{Size, Align};
2626
use rustc_target::spec::abi::Abi;
2727
use rustc_const_eval::const_eval::CheckAlignment;
2828

@@ -766,6 +766,15 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
766766
ecx.machine.check_alignment == AlignmentCheck::Int
767767
}
768768

769+
fn alignment_check_failed(
770+
_ecx: &InterpCx<'mir, 'tcx, Self>,
771+
has: Align,
772+
required: Align,
773+
_check: CheckAlignment,
774+
) -> InterpResult<'tcx, ()> {
775+
throw_ub!(AlignmentCheckFailed { has, required })
776+
}
777+
769778
#[inline(always)]
770779
fn enforce_validity(ecx: &MiriInterpCx<'mir, 'tcx>) -> bool {
771780
ecx.machine.validate

0 commit comments

Comments
 (0)