about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2019-11-27 23:19:03 +0100
committerRalf Jung <post@ralfj.de>2019-11-27 23:33:49 +0100
commit3e7a5a4e0bdf13f504922c9e9b5c539cd57b576f (patch)
tree6aa8df830c92ee1e98db63251c72fcf1ba330bf8
parent04e69e4f4234beb4f12cc76dcc53e2cc4247a9be (diff)
downloadrust-3e7a5a4e0bdf13f504922c9e9b5c539cd57b576f.tar.gz
rust-3e7a5a4e0bdf13f504922c9e9b5c539cd57b576f.zip
handle diverging functions forwarding their return place
-rw-r--r--src/librustc_mir/interpret/place.rs31
1 files changed, 16 insertions, 15 deletions
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 5b263f76801..c03d1da6777 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