diff options
| author | Michael Goulet <michael@errs.io> | 2023-04-04 09:27:44 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-04 09:27:44 -0700 |
| commit | ed17b599dfba4703040bcddb162c8e3419ab95bd (patch) | |
| tree | 2060310a09f5bbf4247f63796941d798adf35e1b /compiler/rustc_const_eval/src | |
| parent | 4d32de6fcbb2ab05e9aaa94477caa30d816f8f66 (diff) | |
| parent | a84909c1e78aef244385b46db080bf78ce548881 (diff) | |
| download | rust-ed17b599dfba4703040bcddb162c8e3419ab95bd.tar.gz rust-ed17b599dfba4703040bcddb162c8e3419ab95bd.zip | |
Rollup merge of #109901 - cjgillot:validate-debuginfo, r=b-naber
Enforce VarDebugInfo::Place in MIR validation.
Diffstat (limited to 'compiler/rustc_const_eval/src')
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/validate.rs | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 558253f727b..e798c9d236e 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -5,13 +5,12 @@ use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; use rustc_infer::traits::Reveal; use rustc_middle::mir::interpret::Scalar; -use rustc_middle::mir::visit::NonUseContext::VarDebugInfo; -use rustc_middle::mir::visit::{PlaceContext, Visitor}; +use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{ traversal, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping, Local, Location, MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, ProjectionElem, RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator, - TerminatorKind, UnOp, START_BLOCK, + TerminatorKind, UnOp, VarDebugInfo, VarDebugInfoContents, START_BLOCK, }; use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt}; use rustc_mir_dataflow::impls::MaybeStorageLive; @@ -419,13 +418,49 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.super_projection_elem(local, proj_base, elem, context, location); } + fn visit_var_debug_info(&mut self, debuginfo: &VarDebugInfo<'tcx>) { + let check_place = |place: Place<'_>| { + if place.projection.iter().any(|p| !p.can_use_in_debuginfo()) { + self.fail( + START_BLOCK.start_location(), + format!("illegal place {:?} in debuginfo for {:?}", place, debuginfo.name), + ); + } + }; + match debuginfo.value { + VarDebugInfoContents::Const(_) => {} + VarDebugInfoContents::Place(place) => check_place(place), + VarDebugInfoContents::Composite { ty, ref fragments } => { + for f in fragments { + check_place(f.contents); + if ty.is_union() || ty.is_enum() { + self.fail( + START_BLOCK.start_location(), + format!("invalid type {:?} for composite debuginfo", ty), + ); + } + if f.projection.iter().any(|p| !matches!(p, PlaceElem::Field(..))) { + self.fail( + START_BLOCK.start_location(), + format!( + "illegal projection {:?} in debuginfo for {:?}", + f.projection, debuginfo.name + ), + ); + } + } + } + } + self.super_var_debug_info(debuginfo); + } + fn visit_place(&mut self, place: &Place<'tcx>, cntxt: PlaceContext, location: Location) { // Set off any `bug!`s in the type computation code let _ = place.ty(&self.body.local_decls, self.tcx); if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) && place.projection.len() > 1 - && cntxt != PlaceContext::NonUse(VarDebugInfo) + && cntxt != PlaceContext::NonUse(NonUseContext::VarDebugInfo) && place.projection[1..].contains(&ProjectionElem::Deref) { self.fail(location, format!("{:?}, has deref at the wrong place", place)); |
