1- use std:: borrow:: Borrow ;
1+ use std:: borrow:: { Borrow , Cow } ;
22use std:: fmt;
33use std:: hash:: Hash ;
44use std:: ops:: ControlFlow ;
55
66use rustc_ast:: Mutability ;
7- use rustc_data_structures:: fx:: { FxIndexMap , IndexEntry } ;
7+ use rustc_data_structures:: fx:: { FxHashMap , FxIndexMap , IndexEntry } ;
88use rustc_hir:: def_id:: { DefId , LocalDefId } ;
99use rustc_hir:: { self as hir, LangItem , CRATE_HIR_ID } ;
1010use rustc_middle:: mir:: AssertMessage ;
1111use rustc_middle:: query:: TyCtxtAt ;
1212use rustc_middle:: ty:: layout:: { FnAbiOf , TyAndLayout } ;
13- use rustc_middle:: ty:: { self , TyCtxt } ;
13+ use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
1414use rustc_middle:: { bug, mir} ;
1515use rustc_span:: symbol:: { sym, Symbol } ;
1616use rustc_span:: Span ;
@@ -24,8 +24,8 @@ use crate::fluent_generated as fluent;
2424use crate :: 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+ fn cached_union_data_range < ' e > (
775+ ecx : & ' e mut InterpCx < ' tcx , Self > ,
776+ ty : Ty < ' tcx > ,
777+ compute_range : impl FnOnce ( ) -> 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
0 commit comments