@@ -45,6 +45,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
45
45
if self . tcx . sess . opts . debugging_opts . mir_emit_validate == 0 {
46
46
return Ok ( ( ) ) ;
47
47
}
48
+ debug_assert ! ( self . memory. cur_frame == self . cur_frame( ) ) ;
48
49
49
50
// HACK: Determine if this method is whitelisted and hence we do not perform any validation.
50
51
// We currently insta-UB on anything passing around uninitialized memory, so we have to whitelist
@@ -55,17 +56,17 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
55
56
use regex:: Regex ;
56
57
lazy_static ! {
57
58
static ref RE : Regex = Regex :: new( "^(\
58
- std::mem::uninitialized::|\
59
- std::mem::forget::|\
59
+ ( std|alloc::heap::__core) ::mem::uninitialized::|\
60
+ ( std|alloc::heap::__core) ::mem::forget::|\
60
61
<(std|alloc)::heap::Heap as (std::heap|alloc::allocator)::Alloc>::|\
61
- <std::mem::ManuallyDrop<T>><.*>::new$|\
62
- <std::mem::ManuallyDrop<T> as std::ops::DerefMut><.*>::deref_mut$|\
63
- std::ptr::read::|\
62
+ <( std|alloc::heap::__core) ::mem::ManuallyDrop<T>><.*>::new$|\
63
+ <( std|alloc::heap::__core) ::mem::ManuallyDrop<T> as std::ops::DerefMut><.*>::deref_mut$|\
64
+ ( std|alloc::heap::__core) ::ptr::read::|\
64
65
\
65
66
<std::sync::Arc<T>><.*>::inner$|\
66
67
<std::sync::Arc<T>><.*>::drop_slow$|\
67
68
(std::heap|alloc::allocator)::Layout::for_value::|\
68
- std::mem::(size|align)_of_val::\
69
+ ( std|alloc::heap::__core) ::mem::(size|align)_of_val::\
69
70
)") . unwrap( ) ;
70
71
}
71
72
// Now test
@@ -93,7 +94,8 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
93
94
if query. mutbl == MutMutable {
94
95
let lft = DynamicLifetime {
95
96
frame : self . cur_frame ( ) ,
96
- region : Some ( scope) ,
97
+ region : Some ( scope) , // Notably, we only ever suspend things for given regions.
98
+ // Suspending for the entire function does not make any sense.
97
99
} ;
98
100
trace ! ( "Suspending {:?} until {:?}" , query, scope) ;
99
101
self . suspended . entry ( lft) . or_insert_with ( Vec :: new) . push (
@@ -106,17 +108,30 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
106
108
self . validate ( query, mode)
107
109
}
108
110
109
- pub ( crate ) fn end_region ( & mut self , scope : region:: Scope ) -> EvalResult < ' tcx > {
110
- self . memory . locks_lifetime_ended ( Some ( scope) ) ;
111
- // Recover suspended lvals
112
- let lft = DynamicLifetime {
113
- frame : self . cur_frame ( ) ,
114
- region : Some ( scope) ,
115
- } ;
116
- if let Some ( queries) = self . suspended . remove ( & lft) {
117
- for query in queries {
118
- trace ! ( "Recovering {:?} from suspension" , query) ;
119
- self . validate ( query, ValidationMode :: Recover ( scope) ) ?;
111
+ /// Release locks and executes suspensions of the given region (or the entire fn, in case of None).
112
+ pub ( crate ) fn end_region ( & mut self , scope : Option < region:: Scope > ) -> EvalResult < ' tcx > {
113
+ debug_assert ! ( self . memory. cur_frame == self . cur_frame( ) ) ;
114
+ self . memory . locks_lifetime_ended ( scope) ;
115
+ match scope {
116
+ Some ( scope) => {
117
+ // Recover suspended lvals
118
+ let lft = DynamicLifetime {
119
+ frame : self . cur_frame ( ) ,
120
+ region : Some ( scope) ,
121
+ } ;
122
+ if let Some ( queries) = self . suspended . remove ( & lft) {
123
+ for query in queries {
124
+ trace ! ( "Recovering {:?} from suspension" , query) ;
125
+ self . validate ( query, ValidationMode :: Recover ( scope) ) ?;
126
+ }
127
+ }
128
+ }
129
+ None => {
130
+ // Clean suspension table of current frame
131
+ let cur_frame = self . cur_frame ( ) ;
132
+ self . suspended . retain ( |lft, _| {
133
+ lft. frame != cur_frame // keep only what is in the other (lower) frames
134
+ } ) ;
120
135
}
121
136
}
122
137
Ok ( ( ) )
@@ -543,7 +558,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
543
558
Ok ( ( ) )
544
559
}
545
560
TyAdt ( adt, subst) => {
546
- if Some ( adt. did ) == self . tcx . lang_items . unsafe_cell_type ( ) &&
561
+ if Some ( adt. did ) == self . tcx . lang_items ( ) . unsafe_cell_type ( ) &&
547
562
query. mutbl == MutImmutable
548
563
{
549
564
// No locks for shared unsafe cells. Also no other validation, the only field is private anyway.
0 commit comments