1
- use std:: borrow:: Borrow ;
1
+ use std:: borrow:: { Borrow , Cow } ;
2
2
use std:: fmt;
3
3
use std:: hash:: Hash ;
4
4
use std:: ops:: ControlFlow ;
5
5
6
6
use rustc_ast:: Mutability ;
7
- use rustc_data_structures:: fx:: { FxIndexMap , IndexEntry } ;
7
+ use rustc_data_structures:: fx:: { FxHashMap , FxIndexMap , IndexEntry } ;
8
8
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
9
9
use rustc_hir:: { self as hir, LangItem , CRATE_HIR_ID } ;
10
10
use rustc_middle:: mir:: AssertMessage ;
11
11
use rustc_middle:: query:: TyCtxtAt ;
12
12
use rustc_middle:: ty:: layout:: { FnAbiOf , TyAndLayout } ;
13
- use rustc_middle:: ty:: { self , TyCtxt } ;
13
+ use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
14
14
use rustc_middle:: { bug, mir} ;
15
15
use rustc_span:: symbol:: { sym, Symbol } ;
16
16
use rustc_span:: Span ;
@@ -24,8 +24,8 @@ use crate::fluent_generated as fluent;
24
24
use crate :: interpret:: {
25
25
self , compile_time_machine, err_ub, throw_exhaust, throw_inval, throw_ub_custom, throw_unsup,
26
26
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 ,
29
29
} ;
30
30
31
31
/// When hitting this many interpreted terminators we emit a deny by default lint
@@ -65,6 +65,9 @@ pub struct CompileTimeMachine<'tcx> {
65
65
/// storing the result in the given `AllocId`.
66
66
/// Used to prevent reads from a static's base allocation, as that may allow for self-initialization loops.
67
67
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 > ,
68
71
}
69
72
70
73
#[ derive( Copy , Clone ) ]
@@ -99,6 +102,7 @@ impl<'tcx> CompileTimeMachine<'tcx> {
99
102
can_access_mut_global,
100
103
check_alignment,
101
104
static_root_ids : None ,
105
+ union_data_ranges : FxHashMap :: default ( ) ,
102
106
}
103
107
}
104
108
}
@@ -766,6 +770,19 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
766
770
}
767
771
Ok ( ( ) )
768
772
}
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
+ }
769
786
}
770
787
771
788
// Please do not add any code below the above `Machine` trait impl. I (oli-obk) plan more cleanups
0 commit comments