1
1
use std:: mem;
2
2
3
- use rustc:: ty:: { self , layout:: { self , Size , Align } } ;
4
3
use rustc:: hir:: def_id:: { DefId , CRATE_DEF_INDEX } ;
5
4
use rustc:: mir;
5
+ use rustc:: ty:: {
6
+ self ,
7
+ layout:: { self , Align , Size } ,
8
+ } ;
6
9
7
10
use rand:: RngCore ;
8
11
@@ -48,7 +51,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
48
51
49
52
/// Write a 0 of the appropriate size to `dest`.
50
53
fn write_null ( & mut self , dest : PlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx > {
51
- self . eval_context_mut ( ) . write_scalar ( Scalar :: from_int ( 0 , dest. layout . size ) , dest)
54
+ self . eval_context_mut ( )
55
+ . write_scalar ( Scalar :: from_int ( 0 , dest. layout . size ) , dest)
52
56
}
53
57
54
58
/// Test if this immediate equals 0.
@@ -61,26 +65,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
61
65
/// Turn a Scalar into an Option<NonNullScalar>
62
66
fn test_null ( & self , val : Scalar < Tag > ) -> InterpResult < ' tcx , Option < Scalar < Tag > > > {
63
67
let this = self . eval_context_ref ( ) ;
64
- Ok ( if this. is_null ( val) ? {
65
- None
66
- } else {
67
- Some ( val)
68
- } )
68
+ Ok ( if this. is_null ( val) ? { None } else { Some ( val) } )
69
69
}
70
70
71
71
/// Get the `Place` for a local
72
72
fn local_place ( & mut self , local : mir:: Local ) -> InterpResult < ' tcx , PlaceTy < ' tcx , Tag > > {
73
73
let this = self . eval_context_mut ( ) ;
74
- let place = mir:: Place { base : mir:: PlaceBase :: Local ( local) , projection : Box :: new ( [ ] ) } ;
74
+ let place = mir:: Place {
75
+ base : mir:: PlaceBase :: Local ( local) ,
76
+ projection : Box :: new ( [ ] ) ,
77
+ } ;
75
78
this. eval_place ( & place)
76
79
}
77
80
78
81
/// Generate some random bytes, and write them to `dest`.
79
- fn gen_random (
80
- & mut self ,
81
- ptr : Scalar < Tag > ,
82
- len : usize ,
83
- ) -> InterpResult < ' tcx > {
82
+ fn gen_random ( & mut self , ptr : Scalar < Tag > , len : usize ) -> InterpResult < ' tcx > {
84
83
// Some programs pass in a null pointer and a length of 0
85
84
// to their platform's random-generation function (e.g. getrandom())
86
85
// on Linux. For compatibility with these programs, we don't perform
@@ -91,26 +90,30 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
91
90
}
92
91
let this = self . eval_context_mut ( ) ;
93
92
94
- let ptr = this. memory ( ) . check_ptr_access (
95
- ptr,
96
- Size :: from_bytes ( len as u64 ) ,
97
- Align :: from_bytes ( 1 ) . unwrap ( )
98
- ) ?. expect ( "we already checked for size 0" ) ;
93
+ let ptr = this
94
+ . memory ( )
95
+ . check_ptr_access (
96
+ ptr,
97
+ Size :: from_bytes ( len as u64 ) ,
98
+ Align :: from_bytes ( 1 ) . unwrap ( ) ,
99
+ ) ?
100
+ . expect ( "we already checked for size 0" ) ;
99
101
100
102
let mut data = vec ! [ 0 ; len] ;
101
103
102
104
if this. machine . communicate {
103
105
// Fill the buffer using the host's rng.
104
106
getrandom:: getrandom ( & mut data)
105
107
. map_err ( |err| err_unsup_format ! ( "getrandom failed: {}" , err) ) ?;
106
- }
107
- else {
108
+ } else {
108
109
let rng = this. memory_mut ( ) . extra . rng . get_mut ( ) ;
109
110
rng. fill_bytes ( & mut data) ;
110
111
}
111
112
112
- let tcx = & { this. tcx . tcx } ;
113
- this. memory_mut ( ) . get_mut ( ptr. alloc_id ) ?. write_bytes ( tcx, ptr, & data)
113
+ let tcx = & { this. tcx . tcx } ;
114
+ this. memory_mut ( )
115
+ . get_mut ( ptr. alloc_id ) ?
116
+ . write_bytes ( tcx, ptr, & data)
114
117
}
115
118
116
119
/// Visits the memory covered by `place`, sensitive to freezing: the 3rd parameter
@@ -123,10 +126,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
123
126
) -> InterpResult < ' tcx > {
124
127
let this = self . eval_context_ref ( ) ;
125
128
trace ! ( "visit_frozen(place={:?}, size={:?})" , * place, size) ;
126
- debug_assert_eq ! ( size,
129
+ debug_assert_eq ! (
130
+ size,
127
131
this. size_and_align_of_mplace( place) ?
128
- . map( |( size, _) | size)
129
- . unwrap_or_else( || place. layout. size)
132
+ . map( |( size, _) | size)
133
+ . unwrap_or_else( || place. layout. size)
130
134
) ;
131
135
// Store how far we proceeded into the place so far. Everything to the left of
132
136
// this offset has already been handled, in the sense that the frozen parts
@@ -146,11 +150,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
146
150
let frozen_size = unsafe_cell_offset - end_offset;
147
151
// Everything between the end_ptr and this `UnsafeCell` is frozen.
148
152
if frozen_size != Size :: ZERO {
149
- action ( end_ptr, frozen_size, /*frozen*/ true ) ?;
153
+ action ( end_ptr, frozen_size, /*frozen*/ true ) ?;
150
154
}
151
155
// This `UnsafeCell` is NOT frozen.
152
156
if unsafe_cell_size != Size :: ZERO {
153
- action ( unsafe_cell_ptr, unsafe_cell_size, /*frozen*/ false ) ?;
157
+ action ( unsafe_cell_ptr, unsafe_cell_size, /*frozen*/ false ) ?;
154
158
}
155
159
// Update end end_ptr.
156
160
end_ptr = unsafe_cell_ptr. wrapping_offset ( unsafe_cell_size, this) ;
@@ -164,7 +168,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
164
168
unsafe_cell_action : |place| {
165
169
trace ! ( "unsafe_cell_action on {:?}" , place. ptr) ;
166
170
// We need a size to go on.
167
- let unsafe_cell_size = this. size_and_align_of_mplace ( place) ?
171
+ let unsafe_cell_size = this
172
+ . size_and_align_of_mplace ( place) ?
168
173
. map ( |( size, _) | size)
169
174
// for extern types, just cover what we can
170
175
. unwrap_or_else ( || place. layout . size ) ;
@@ -187,18 +192,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
187
192
/// Visiting the memory covered by a `MemPlace`, being aware of
188
193
/// whether we are inside an `UnsafeCell` or not.
189
194
struct UnsafeCellVisitor < ' ecx , ' mir , ' tcx , F >
190
- where F : FnMut ( MPlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx >
195
+ where
196
+ F : FnMut ( MPlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx > ,
191
197
{
192
198
ecx : & ' ecx MiriEvalContext < ' mir , ' tcx > ,
193
199
unsafe_cell_action : F ,
194
200
}
195
201
196
- impl < ' ecx , ' mir , ' tcx , F >
197
- ValueVisitor < ' mir , ' tcx , Evaluator < ' tcx > >
198
- for
199
- UnsafeCellVisitor < ' ecx , ' mir , ' tcx , F >
202
+ impl < ' ecx , ' mir , ' tcx , F > ValueVisitor < ' mir , ' tcx , Evaluator < ' tcx > >
203
+ for UnsafeCellVisitor < ' ecx , ' mir , ' tcx , F >
200
204
where
201
- F : FnMut ( MPlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx >
205
+ F : FnMut ( MPlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx > ,
202
206
{
203
207
type V = MPlaceTy < ' tcx , Tag > ;
204
208
@@ -208,11 +212,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
208
212
}
209
213
210
214
// Hook to detect `UnsafeCell`.
211
- fn visit_value ( & mut self , v : MPlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx >
212
- {
215
+ fn visit_value ( & mut self , v : MPlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx > {
213
216
trace ! ( "UnsafeCellVisitor: {:?} {:?}" , * v, v. layout. ty) ;
214
217
let is_unsafe_cell = match v. layout . ty . kind {
215
- ty:: Adt ( adt, _) => Some ( adt. did ) == self . ecx . tcx . lang_items ( ) . unsafe_cell_type ( ) ,
218
+ ty:: Adt ( adt, _) => {
219
+ Some ( adt. did ) == self . ecx . tcx . lang_items ( ) . unsafe_cell_type ( )
220
+ }
216
221
_ => false ,
217
222
} ;
218
223
if is_unsafe_cell {
@@ -249,7 +254,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
249
254
fn visit_aggregate (
250
255
& mut self ,
251
256
place : MPlaceTy < ' tcx , Tag > ,
252
- fields : impl Iterator < Item = InterpResult < ' tcx , MPlaceTy < ' tcx , Tag > > > ,
257
+ fields : impl Iterator < Item = InterpResult < ' tcx , MPlaceTy < ' tcx , Tag > > > ,
253
258
) -> InterpResult < ' tcx > {
254
259
match place. layout . fields {
255
260
layout:: FieldPlacement :: Array { .. } => {
@@ -259,7 +264,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
259
264
}
260
265
layout:: FieldPlacement :: Arbitrary { .. } => {
261
266
// Gather the subplaces and sort them before visiting.
262
- let mut places = fields. collect :: < InterpResult < ' tcx , Vec < MPlaceTy < ' tcx , Tag > > > > ( ) ?;
267
+ let mut places =
268
+ fields. collect :: < InterpResult < ' tcx , Vec < MPlaceTy < ' tcx , Tag > > > > ( ) ?;
263
269
places. sort_by_key ( |place| place. ptr . assert_ptr ( ) . offset ) ;
264
270
self . walk_aggregate ( place, places. into_iter ( ) . map ( Ok ) )
265
271
}
@@ -271,8 +277,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
271
277
}
272
278
273
279
// We have to do *something* for unions.
274
- fn visit_union ( & mut self , v : MPlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx >
275
- {
280
+ fn visit_union ( & mut self , v : MPlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx > {
276
281
// With unions, we fall back to whatever the type says, to hopefully be consistent
277
282
// with LLVM IR.
278
283
// FIXME: are we consistent, and is this really the behavior we want?
@@ -285,8 +290,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
285
290
}
286
291
287
292
// We should never get to a primitive, but always short-circuit somewhere above.
288
- fn visit_primitive ( & mut self , _v : MPlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx >
289
- {
293
+ fn visit_primitive ( & mut self , _v : MPlaceTy < ' tcx , Tag > ) -> InterpResult < ' tcx > {
290
294
bug ! ( "we should always short-circuit before coming to a primitive" )
291
295
}
292
296
}
@@ -296,12 +300,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
296
300
fn eval_libc ( & mut self , name : & str ) -> InterpResult < ' tcx , Scalar < Tag > > {
297
301
self . eval_context_mut ( )
298
302
. eval_path_scalar ( & [ "libc" , name] ) ?
299
- . ok_or_else ( || err_unsup_format ! ( "Path libc::{} cannot be resolved." , name) . into ( ) )
300
- . and_then ( |scalar| scalar . not_undef ( ) )
303
+ . ok_or_else ( || err_unsup_format ! ( "Path libc::{} cannot be resolved." , name) ) ?
304
+ . not_undef ( )
301
305
}
302
306
303
307
/// Helper function to get a `libc` constant as an `i32`.
304
308
fn eval_libc_i32 ( & mut self , name : & str ) -> InterpResult < ' tcx , i32 > {
305
- self . eval_libc ( name) . and_then ( |scalar| scalar . to_i32 ( ) )
309
+ self . eval_libc ( name) ? . to_i32 ( )
306
310
}
307
311
}
0 commit comments