Skip to content

Commit

Permalink
Rollup merge of #66827 - RalfJung:miri-missing-ret-place, r=oli-obk
Browse files Browse the repository at this point in the history
handle diverging functions forwarding their return place

Fixes rust-lang/miri#1075: the shim around diverging closures turned into function pointers actually "obtains" a return place inside a diverging function, but just uses it as the return place for a diverging callee. Handle this by using NULL places.

This is kind of a hack as it breaks our invariant that all places are dereferencable, but we'd eventually let raw pointers break that anyway I assume so that seems fine.

r? @oli-obk
  • Loading branch information
RalfJung authored Dec 2, 2019
2 parents b7f8b77 + 2869aba commit 3134368
Showing 1 changed file with 23 additions and 15 deletions.
38 changes: 23 additions & 15 deletions src/librustc_mir/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -651,20 +651,28 @@ where
use rustc::mir::PlaceBase;

let mut place_ty = match &place.base {
PlaceBase::Local(mir::RETURN_PLACE) => match self.frame().return_place {
Some(return_place) => {
// We use our layout to verify our assumption; caller will validate
// their layout on return.
PlaceTy {
place: *return_place,
layout: self.layout_of(
self.subst_from_frame_and_normalize_erasing_regions(
self.frame().body.return_ty()
)
)?,
}
PlaceBase::Local(mir::RETURN_PLACE) => {
// `return_place` has the *caller* layout, but we want to use our
// `layout to verify our assumption. The caller will validate
// their layout on return.
PlaceTy {
place: match self.frame().return_place {
Some(p) => *p,
// Even if we don't have a return place, we sometimes need to
// create this place, but any attempt to read from / write to it
// (even a ZST read/write) needs to error, so let us make this
// a NULL place.
//
// FIXME: Ideally we'd make sure that the place projections also
// bail out.
None => Place::null(&*self),
},
layout: self.layout_of(
self.subst_from_frame_and_normalize_erasing_regions(
self.frame().body.return_ty()
)
)?,
}
None => throw_unsup!(InvalidNullPointerUsage),
},
PlaceBase::Local(local) => PlaceTy {
// This works even for dead/uninitialized locals; we check further when writing
Expand Down Expand Up @@ -791,8 +799,8 @@ where
// to handle padding properly, which is only correct if we never look at this data with the
// wrong type.

let ptr = match self.check_mplace_access(dest, None)
.expect("places should be checked on creation")
// Invalid places are a thing: the return place of a diverging function
let ptr = match self.check_mplace_access(dest, None)?
{
Some(ptr) => ptr,
None => return Ok(()), // zero-sized access
Expand Down

0 comments on commit 3134368

Please sign in to comment.