Skip to content

Commit 6b7686f

Browse files
committed
do not look at refs to external statics at all
1 parent 9a6df47 commit 6b7686f

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

src/librustc_mir/interpret/validity.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,25 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
254254
place: MPlaceTy<'tcx>,
255255
path: &mut Vec<PathElem>,
256256
ref_tracking: Option<&mut RefTracking<'tcx>>,
257+
const_mode: bool,
257258
) -> 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.
259276
let (size, align) = self.size_and_align_of(place.extra, place.layout)?;
260277
try_validation!(self.memory.check_align(place.ptr, align),
261278
"unaligned reference", path);
@@ -264,24 +281,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
264281
"integer pointer in non-ZST reference", path);
265282
try_validation!(self.memory.check_bounds(ptr, size, false),
266283
"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-
}
278284
}
279285
// Check if we have encountered this pointer+layout combination
280286
// before. Proceed recursively even for integer pointers, no
281287
// reason to skip them! They are valid for some ZST, but not for others
282288
// (e.g. `!` is a ZST).
283-
let op = place.into();
284289
if let Some(ref_tracking) = ref_tracking {
290+
let op = place.into();
285291
if ref_tracking.seen.insert(op) {
286292
trace!("Recursing below ptr {:#?}", *op);
287293
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>
399405
self.validate_ref(
400406
self.ref_to_mplace(value)?,
401407
path,
402-
ref_tracking
408+
ref_tracking,
409+
const_mode,
403410
)?;
404411
}
405412
},
@@ -437,7 +444,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
437444
}
438445
// for safe ptrs, recursively check it
439446
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)?;
441448
}
442449
}
443450
// Compound data structures

0 commit comments

Comments
 (0)