From 3e7a5a4e0bdf13f504922c9e9b5c539cd57b576f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 27 Nov 2019 23:19:03 +0100 Subject: [PATCH 1/2] handle diverging functions forwarding their return place --- src/librustc_mir/interpret/place.rs | 31 +++++++++++++++-------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 5b263f7680131..c03d1da677758 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -651,20 +651,21 @@ 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, + 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 @@ -791,8 +792,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 From 2869abacfa12ce3946234e5554d160fc932d933d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 27 Nov 2019 23:36:39 +0100 Subject: [PATCH 2/2] comment --- src/librustc_mir/interpret/place.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index c03d1da677758..70d9836b6ff0f 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -658,6 +658,13 @@ where 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(