Skip to content

Commit 8cd982c

Browse files
committed
interpret: reset padding during validation
1 parent cbdcbf0 commit 8cd982c

24 files changed

Lines changed: 584 additions & 50 deletions

‎compiler/rustc_const_eval/src/const_eval/machine.rs‎

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
use std::borrow::Borrow;
1+
use std::borrow::{Borrow,Cow};
22
use std::fmt;
33
use std::hash::Hash;
44
use std::ops::ControlFlow;
55

66
use rustc_ast::Mutability;
7-
use rustc_data_structures::fx::{FxIndexMap,IndexEntry};
7+
use rustc_data_structures::fx::{FxHashMap,FxIndexMap,IndexEntry};
88
use rustc_hir::def_id::{DefId,LocalDefId};
99
use rustc_hir::{selfas hir,LangItem,CRATE_HIR_ID};
1010
use rustc_middle::mir::AssertMessage;
1111
use rustc_middle::query::TyCtxtAt;
1212
use rustc_middle::ty::layout::{FnAbiOf,TyAndLayout};
13-
use rustc_middle::ty::{self,TyCtxt};
13+
use rustc_middle::ty::{self,Ty,TyCtxt};
1414
use rustc_middle::{bug, mir};
1515
use rustc_span::symbol::{sym,Symbol};
1616
use rustc_span::Span;
@@ -24,8 +24,8 @@ use crate::fluent_generated as fluent;
2424
usecrate::interpret::{
2525
self, compile_time_machine, err_ub, throw_exhaust, throw_inval, throw_ub_custom, throw_unsup,
2626
throw_unsup_format,AllocId,AllocRange,ConstAllocation,CtfeProvenance,FnArg,Frame,
27-
GlobalAlloc,ImmTy,InterpCx,InterpResult,MPlaceTy,OpTy,Pointer,PointerArithmetic,Scalar,
28-
StackPopCleanup,
27+
GlobalAlloc,ImmTy,InterpCx,InterpResult,MPlaceTy,OpTy,Pointer,PointerArithmetic,
28+
RangeSet,Scalar,StackPopCleanup,
2929
};
3030

3131
/// When hitting this many interpreted terminators we emit a deny by default lint
@@ -65,6 +65,9 @@ pub struct CompileTimeMachine<'tcx> {
6565
/// storing the result in the given `AllocId`.
6666
/// Used to prevent reads from a static's base allocation, as that may allow for self-initialization loops.
6767
pub(crate)static_root_ids:Option<(AllocId,LocalDefId)>,
68+
69+
/// A cache of "data range" computations for unions (i.e., the offsets of non-padding bytes).
70+
union_data_ranges:FxHashMap<Ty<'tcx>,RangeSet>,
6871
}
6972

7073
#[derive(Copy,Clone)]
@@ -99,6 +102,7 @@ impl<'tcx> CompileTimeMachine<'tcx> {
99102
can_access_mut_global,
100103
check_alignment,
101104
static_root_ids:None,
105+
union_data_ranges:FxHashMap::default(),
102106
}
103107
}
104108
}
@@ -766,6 +770,19 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
766770
}
767771
Ok(())
768772
}
773+
774+
fncached_union_data_range<'e>(
775+
ecx:&'emutInterpCx<'tcx,Self>,
776+
ty:Ty<'tcx>,
777+
compute_range:implFnOnce() -> RangeSet,
778+
) -> Cow<'e,RangeSet>{
779+
if ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks{
780+
Cow::Borrowed(ecx.machine.union_data_ranges.entry(ty).or_insert_with(compute_range))
781+
}else{
782+
// Don't bother caching, we're only doing one validation at the end anyway.
783+
Cow::Owned(compute_range())
784+
}
785+
}
769786
}
770787

771788
// Please do not add any code below the above `Machine` trait impl. I (oli-obk) plan more cleanups

‎compiler/rustc_const_eval/src/interpret/machine.rs‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_apfloat::{Float, FloatConvert};
1010
use rustc_ast::{InlineAsmOptions,InlineAsmTemplatePiece};
1111
use rustc_middle::query::TyCtxtAt;
1212
use rustc_middle::ty::layout::TyAndLayout;
13+
use rustc_middle::ty::Ty;
1314
use rustc_middle::{mir, ty};
1415
use rustc_span::def_id::DefId;
1516
use rustc_span::Span;
@@ -19,7 +20,7 @@ use rustc_target::spec::abi::Abi as CallAbi;
1920
usesuper::{
2021
throw_unsup, throw_unsup_format,AllocBytes,AllocId,AllocKind,AllocRange,Allocation,
2122
ConstAllocation,CtfeProvenance,FnArg,Frame,ImmTy,InterpCx,InterpResult,MPlaceTy,
22-
MemoryKind,Misalignment,OpTy,PlaceTy,Pointer,Provenance,CTFE_ALLOC_SALT,
23+
MemoryKind,Misalignment,OpTy,PlaceTy,Pointer,Provenance,RangeSet,CTFE_ALLOC_SALT,
2324
};
2425

2526
/// Data returned by [`Machine::after_stack_pop`], and consumed by
@@ -578,6 +579,15 @@ pub trait Machine<'tcx>: Sized {
578579
ecx:&InterpCx<'tcx,Self>,
579580
instance:Option<ty::Instance<'tcx>>,
580581
) -> usize;
582+
583+
fncached_union_data_range<'e>(
584+
_ecx:&'emutInterpCx<'tcx,Self>,
585+
_ty:Ty<'tcx>,
586+
compute_range:implFnOnce() -> RangeSet,
587+
) -> Cow<'e,RangeSet>{
588+
// Default to no caching.
589+
Cow::Owned(compute_range())
590+
}
581591
}
582592

583593
/// A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines

‎compiler/rustc_const_eval/src/interpret/memory.rs‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1136,8 +1136,17 @@ impl<'tcx, 'a, Prov: Provenance, Extra, Bytes: AllocBytes>
11361136
self.write_scalar(alloc_range(offset,self.tcx.data_layout().pointer_size), val)
11371137
}
11381138

1139+
/// Mark the given sub-range (relative to this allocation reference) as uninitialized.
1140+
pubfnwrite_uninit(&mutself,range:AllocRange) -> InterpResult<'tcx>{
1141+
let range = self.range.subrange(range);
1142+
Ok(self
1143+
.alloc
1144+
.write_uninit(&self.tcx, range)
1145+
.map_err(|e| e.to_interp_error(self.alloc_id))?)
1146+
}
1147+
11391148
/// Mark the entire referenced range as uninitialized
1140-
pubfnwrite_uninit(&mutself) -> InterpResult<'tcx>{
1149+
pubfnwrite_uninit_full(&mutself) -> InterpResult<'tcx>{
11411150
Ok(self
11421151
.alloc
11431152
.write_uninit(&self.tcx,self.range)

‎compiler/rustc_const_eval/src/interpret/mod.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,5 @@ use self::place::{MemPlace, Place};
3939
pubuseself::projection::{OffsetMode,Projectable};
4040
pubuseself::stack::{Frame,FrameInfo,LocalState,StackPopCleanup,StackPopInfo};
4141
pub(crate)useself::util::create_static_alloc;
42-
pubuseself::validity::{CtfeValidationMode,RefTracking};
42+
pubuseself::validity::{CtfeValidationMode,RangeSet,RefTracking};
4343
pubuseself::visitor::ValueVisitor;

‎compiler/rustc_const_eval/src/interpret/place.rs‎

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -604,10 +604,11 @@ where
604604

605605
ifM::enforce_validity(self, dest.layout()){
606606
// Data got changed, better make sure it matches the type!
607+
// Also needed to reset padding.
607608
self.validate_operand(
608609
&dest.to_place(),
609610
M::enforce_validity_recursively(self, dest.layout()),
610-
/*reset_provenance*/true,
611+
/*reset_provenance_and_padding*/true,
611612
)?;
612613
}
613614

@@ -703,9 +704,11 @@ where
703704
// fields do not match the `ScalarPair` components.
704705

705706
alloc.write_scalar(alloc_range(Size::ZERO, a_val.size()), a_val)?;
706-
alloc.write_scalar(alloc_range(b_offset, b_val.size()), b_val)
707+
alloc.write_scalar(alloc_range(b_offset, b_val.size()), b_val)?;
708+
// We don't have to reset padding here, `write_immediate` will anyway do a validation run.
709+
Ok(())
707710
}
708-
Immediate::Uninit => alloc.write_uninit(),
711+
Immediate::Uninit => alloc.write_uninit_full(),
709712
}
710713
}
711714

@@ -722,7 +725,7 @@ where
722725
// Zero-sized access
723726
returnOk(());
724727
};
725-
alloc.write_uninit()?;
728+
alloc.write_uninit_full()?;
726729
}
727730
}
728731
Ok(())
@@ -814,17 +817,17 @@ where
814817
// Given that there were two typed copies, we have to ensure this is valid at both types,
815818
// and we have to ensure this loses provenance and padding according to both types.
816819
// But if the types are identical, we only do one pass.
817-
if src.layout().ty != dest.layout().ty{
820+
ifallow_transmute && src.layout().ty != dest.layout().ty{
818821
self.validate_operand(
819822
&dest.transmute(src.layout(),self)?,
820823
M::enforce_validity_recursively(self, src.layout()),
821-
/*reset_provenance*/true,
824+
/*reset_provenance_and_padding*/true,
822825
)?;
823826
}
824827
self.validate_operand(
825828
&dest,
826829
M::enforce_validity_recursively(self, dest.layout()),
827-
/*reset_provenance*/true,
830+
/*reset_provenance_and_padding*/true,
828831
)?;
829832
}
830833

0 commit comments

Comments
 (0)