about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-08-15 04:32:17 +0000
committerbors <bors@rust-lang.org>2017-08-15 04:32:17 +0000
commitf6a30bd37b68d4d474fa3c3b49df29637fe3c369 (patch)
treec9c0212983bb3b25eb0d18f9af77c2f260d22c9e
parentdf806275c7c87865080bed9e809a7a693392c666 (diff)
parente3495b2cfa2dab62cfa189210a97f4235e73e865 (diff)
downloadrust-f6a30bd37b68d4d474fa3c3b49df29637fe3c369.tar.gz
rust-f6a30bd37b68d4d474fa3c3b49df29637fe3c369.zip
Auto merge of #43859 - arielb1:nonfree-block-live, r=nagisa
emit StorageLive for box temporaries

We started emitting StorageDead, so we better emit the corrseponding
StorageLive to avoid problems.

cc #43772 solson/miri#303
-rw-r--r--src/librustc_mir/build/expr/as_rvalue.rs12
-rw-r--r--src/test/mir-opt/box_expr.rs88
2 files changed, 97 insertions, 3 deletions
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index 8974c4ec1fb..a625f4b0458 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -97,13 +97,19 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             ExprKind::Box { value } => {
                 let value = this.hir.mirror(value);
                 let result = this.temp(expr.ty, expr_span);
-                // to start, malloc some memory of suitable type (thus far, uninitialized):
-                let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
-                this.cfg.push_assign(block, source_info, &result, box_);
                 if let Some(scope) = scope {
                     // schedule a shallow free of that memory, lest we unwind:
+                    this.cfg.push(block, Statement {
+                        source_info: source_info,
+                        kind: StatementKind::StorageLive(result.clone())
+                    });
                     this.schedule_drop(expr_span, scope, &result, value.ty);
                 }
+
+                // malloc some memory of suitable type (thus far, uninitialized):
+                let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
+                this.cfg.push_assign(block, source_info, &result, box_);
+
                 // initialize the box contents:
                 unpack!(block = this.into(&result.clone().deref(), block, value));
                 block.and(Rvalue::Use(Operand::Consume(result)))
diff --git a/src/test/mir-opt/box_expr.rs b/src/test/mir-opt/box_expr.rs
new file mode 100644
index 00000000000..4015930ef76
--- /dev/null
+++ b/src/test/mir-opt/box_expr.rs
@@ -0,0 +1,88 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(box_syntax)]
+
+fn main() {
+    let x = box S::new();
+    drop(x);
+}
+
+struct S;
+
+impl S {
+    fn new() -> Self { S }
+}
+
+impl Drop for S {
+    fn drop(&mut self) {
+        println!("splat!");
+    }
+}
+
+// END RUST SOURCE
+// START rustc.node4.ElaborateDrops.before.mir
+//     let mut _0: ();
+//     let _1: std::boxed::Box<S>;
+//     let mut _2: std::boxed::Box<S>;
+//     let mut _3: ();
+//     let mut _4: std::boxed::Box<S>;
+//
+//     bb0: {
+//         StorageLive(_1);
+//         StorageLive(_2);
+//         _2 = Box(S);
+//         (*_2) = const S::new() -> [return: bb1, unwind: bb3];
+//     }
+//
+//     bb1: {
+//         _1 = _2;
+//         drop(_2) -> bb4;
+//     }
+//
+//     bb2: {
+//         resume;
+//     }
+//
+//     bb3: {
+//         drop(_2) -> bb2;
+//     }
+//
+//     bb4: {
+//         StorageDead(_2);
+//         StorageLive(_4);
+//         _4 = _1;
+//         _3 = const std::mem::drop(_4) -> [return: bb5, unwind: bb7];
+//     }
+//
+//     bb5: {
+//         drop(_4) -> [return: bb8, unwind: bb6];
+//     }
+//
+//     bb6: {
+//         drop(_1) -> bb2;
+//     }
+//
+//     bb7: {
+//         drop(_4) -> bb6;
+//     }
+//
+//     bb8: {
+//         StorageDead(_4);
+//         _0 = ();
+//         drop(_1) -> bb9;
+//     }
+//
+//     bb9: {
+//         StorageDead(_1);
+//         return;
+//     }
+// }
+// END rustc.node4.ElaborateDrops.before.mir