@@ -254,8 +254,25 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
254
254
place : MPlaceTy < ' tcx > ,
255
255
path : & mut Vec < PathElem > ,
256
256
ref_tracking : Option < & mut RefTracking < ' tcx > > ,
257
+ const_mode : bool ,
257
258
) -> EvalResult < ' tcx > {
258
- // Before we do anything else, make sure this is entirely in-bounds.
259
+ if const_mode {
260
+ // Skip validation entirely for some external statics
261
+ if let Scalar :: Ptr ( ptr) = place. ptr {
262
+ let alloc_kind = self . tcx . alloc_map . lock ( ) . get ( ptr. alloc_id ) ;
263
+ if let Some ( AllocType :: Static ( did) ) = alloc_kind {
264
+ // `extern static` cannot be validated as they have no body.
265
+ // They are not even properly aligned.
266
+ // Statics from other crates are already checked.
267
+ // They might be checked at a different type, but for now we want
268
+ // to avoid recursing too deeply. This is not sound!
269
+ if !did. is_local ( ) || self . tcx . is_foreign_item ( did) {
270
+ return Ok ( ( ) ) ;
271
+ }
272
+ }
273
+ }
274
+ }
275
+ // Make sure this is non-NULL, aligned and entirely in-bounds.
259
276
let ( size, align) = self . size_and_align_of ( place. extra , place. layout ) ?;
260
277
try_validation ! ( self . memory. check_align( place. ptr, align) ,
261
278
"unaligned reference" , path) ;
@@ -264,24 +281,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
264
281
"integer pointer in non-ZST reference" , path) ;
265
282
try_validation ! ( self . memory. check_bounds( ptr, size, false ) ,
266
283
"dangling reference (not entirely in bounds)" , path) ;
267
- // Skip recursion for some external statics
268
- let alloc_kind = self . tcx . alloc_map . lock ( ) . get ( ptr. alloc_id ) ;
269
- if let Some ( AllocType :: Static ( did) ) = alloc_kind {
270
- // statics from other crates are already checked.
271
- // they might be checked at a different type, but for now we want
272
- // to avoid recursing too deeply.
273
- // extern statics cannot be validated as they have no body.
274
- if !did. is_local ( ) || self . tcx . is_foreign_item ( did) {
275
- return Ok ( ( ) ) ;
276
- }
277
- }
278
284
}
279
285
// Check if we have encountered this pointer+layout combination
280
286
// before. Proceed recursively even for integer pointers, no
281
287
// reason to skip them! They are valid for some ZST, but not for others
282
288
// (e.g. `!` is a ZST).
283
- let op = place. into ( ) ;
284
289
if let Some ( ref_tracking) = ref_tracking {
290
+ let op = place. into ( ) ;
285
291
if ref_tracking. seen . insert ( op) {
286
292
trace ! ( "Recursing below ptr {:#?}" , * op) ;
287
293
ref_tracking. todo . push ( ( op, path_clone_and_deref ( path) ) ) ;
@@ -399,7 +405,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
399
405
self . validate_ref (
400
406
self . ref_to_mplace ( value) ?,
401
407
path,
402
- ref_tracking
408
+ ref_tracking,
409
+ const_mode,
403
410
) ?;
404
411
}
405
412
} ,
@@ -437,7 +444,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
437
444
}
438
445
// for safe ptrs, recursively check it
439
446
if !dest. layout . ty . is_unsafe_ptr ( ) {
440
- self . validate_ref ( ptr, path, ref_tracking) ?;
447
+ self . validate_ref ( ptr, path, ref_tracking, const_mode ) ?;
441
448
}
442
449
}
443
450
// Compound data structures
0 commit comments