about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2016-01-11 18:23:22 +0100
committerFelix S. Klock II <pnkfelix@pnkfx.org>2016-01-13 14:02:06 +0100
commitf251ff4081dc89b984000547ec0903e845f14201 (patch)
tree1d4a6e63b7424e89315577d5535477da382e04c3
parentcec7280bf367be9da472e02eba59b5440b5336c9 (diff)
bug fixes for issues 30018 and 30822.
includes bugfixes pointed out during review:

 * Only `call_lifetime_start` for an alloca if the function entry does
   not itself initialize it to "dropped."

 * Remove `schedule_lifetime_end` after writing an *element* into a
   borrowed slice. (As explained by [dotdash][irc], "the lifetime end
   that is being removed was for an element in the slice, which is not
   an alloca of its own and has no lifetime start of its own")

[irc]: https://botbot.me/mozilla/rust-internals/2016-01-13/?msg=57844504&page=3
-rw-r--r--src/librustc_trans/trans/tvec.rs15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs
index c7e1af5853d..3a1568a70c9 100644
--- a/src/librustc_trans/trans/tvec.rs
+++ b/src/librustc_trans/trans/tvec.rs
@@ -111,8 +111,15 @@ pub fn trans_slice_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     // Always create an alloca even if zero-sized, to preserve
     // the non-null invariant of the inner slice ptr
-    let llfixed = base::alloc_ty(bcx, fixed_ty, "");
-    call_lifetime_start(bcx, llfixed);
+    let llfixed;
+    // Issue 30018: ensure state is initialized as dropped if necessary.
+    if fcx.type_needs_drop(vt.unit_ty) {
+        llfixed = base::alloc_ty_init(bcx, fixed_ty, InitAlloca::Dropped, "");
+    } else {
+        let uninit = InitAlloca::Uninit("fcx says vt.unit_ty is non-drop");
+        llfixed = base::alloc_ty_init(bcx, fixed_ty, uninit, "");
+        call_lifetime_start(bcx, llfixed);
+    };
 
     if count > 0 {
         // Arrange for the backing array to be cleaned up.
@@ -212,8 +219,8 @@ fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                         bcx = expr::trans_into(bcx, &**element,
                                                SaveIn(lleltptr));
                         let scope = cleanup::CustomScope(temp_scope);
-                        fcx.schedule_lifetime_end(scope, lleltptr);
-                        fcx.schedule_drop_mem(scope, lleltptr, vt.unit_ty, None);
+                        // Issue #30822: mark memory as dropped after running destructor
+                        fcx.schedule_drop_and_fill_mem(scope, lleltptr, vt.unit_ty, None);
                     }
                     fcx.pop_custom_cleanup_scope(temp_scope);
                 }