@@ -1285,12 +1285,62 @@ fn memfill<'a, 'tcx>(b: &Builder<'a, 'tcx>, llptr: ValueRef, ty: Ty<'tcx>, byte:
1285
1285
None ) ;
1286
1286
}
1287
1287
1288
- pub fn alloc_ty < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > , t : Ty < ' tcx > , name : & str ) -> ValueRef {
1288
+ /// In general, when we create an scratch value in an alloca, the
1289
+ /// creator may not know if the block (that initializes the scratch
1290
+ /// with the desired value) actually dominates the cleanup associated
1291
+ /// with the scratch value.
1292
+ ///
1293
+ /// To deal with this, when we do an alloca (at the *start* of whole
1294
+ /// function body), we optionally can also set the associated
1295
+ /// dropped-flag state of the alloca to "dropped."
1296
+ #[ derive( Copy , Clone , Debug ) ]
1297
+ pub enum InitAlloca {
1298
+ /// Indicates that the state should have its associated drop flag
1299
+ /// set to "dropped" at the point of allocation.
1300
+ Dropped ,
1301
+ /// Indicates the value of the associated drop flag is irrelevant.
1302
+ /// The embedded string literal is a programmer provided argument
1303
+ /// for why. This is a safeguard forcing compiler devs to
1304
+ /// document; it might be a good idea to also emit this as a
1305
+ /// comment with the alloca itself when emitting LLVM output.ll.
1306
+ Uninit ( & ' static str ) ,
1307
+ }
1308
+
1309
+
1310
+ pub fn alloc_ty < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > ,
1311
+ t : Ty < ' tcx > ,
1312
+ name : & str ) -> ValueRef {
1313
+ // pnkfelix: I do not know why alloc_ty meets the assumptions for
1314
+ // passing Uninit, but it was never needed (even back when we had
1315
+ // the original boolean `zero` flag on `lvalue_scratch_datum`).
1316
+ alloc_ty_init ( bcx, t, InitAlloca :: Uninit ( "all alloc_ty are uninit" ) , name)
1317
+ }
1318
+
1319
+ pub fn alloc_ty_init < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > ,
1320
+ t : Ty < ' tcx > ,
1321
+ init : InitAlloca ,
1322
+ name : & str ) -> ValueRef {
1289
1323
let _icx = push_ctxt ( "alloc_ty" ) ;
1290
1324
let ccx = bcx. ccx ( ) ;
1291
1325
let ty = type_of:: type_of ( ccx, t) ;
1292
1326
assert ! ( !t. has_param_types( ) ) ;
1293
- alloca ( bcx, ty, name)
1327
+ match init {
1328
+ InitAlloca :: Dropped => alloca_dropped ( bcx, t, name) ,
1329
+ InitAlloca :: Uninit ( _) => alloca ( bcx, ty, name) ,
1330
+ }
1331
+ }
1332
+
1333
+ pub fn alloca_dropped < ' blk , ' tcx > ( cx : Block < ' blk , ' tcx > , ty : Ty < ' tcx > , name : & str ) -> ValueRef {
1334
+ let _icx = push_ctxt ( "alloca_dropped" ) ;
1335
+ let llty = type_of:: type_of ( cx. ccx ( ) , ty) ;
1336
+ if cx. unreachable . get ( ) {
1337
+ unsafe { return llvm:: LLVMGetUndef ( llty. ptr_to ( ) . to_ref ( ) ) ; }
1338
+ }
1339
+ let p = alloca ( cx, llty, name) ;
1340
+ let b = cx. fcx . ccx . builder ( ) ;
1341
+ b. position_before ( cx. fcx . alloca_insert_pt . get ( ) . unwrap ( ) ) ;
1342
+ memfill ( & b, p, ty, adt:: DTOR_DONE ) ;
1343
+ p
1294
1344
}
1295
1345
1296
1346
pub fn alloca ( cx : Block , ty : Type , name : & str ) -> ValueRef {
@@ -1650,6 +1700,7 @@ pub fn create_datums_for_fn_args<'a, 'tcx>(mut bcx: Block<'a, 'tcx>,
1650
1700
// This alloca should be optimized away by LLVM's mem-to-reg pass in
1651
1701
// the event it's not truly needed.
1652
1702
let mut idx = fcx. arg_offset ( ) as c_uint ;
1703
+ let uninit_reason = InitAlloca :: Uninit ( "fn_arg populate dominates dtor" ) ;
1653
1704
for ( i, & arg_ty) in arg_tys. iter ( ) . enumerate ( ) {
1654
1705
let arg_datum = if !has_tupled_arg || i < arg_tys. len ( ) - 1 {
1655
1706
if type_of:: arg_is_indirect ( bcx. ccx ( ) , arg_ty) &&
@@ -1669,7 +1720,7 @@ pub fn create_datums_for_fn_args<'a, 'tcx>(mut bcx: Block<'a, 'tcx>,
1669
1720
let data = get_param ( fcx. llfn , idx) ;
1670
1721
let extra = get_param ( fcx. llfn , idx + 1 ) ;
1671
1722
idx += 2 ;
1672
- unpack_datum ! ( bcx, datum:: lvalue_scratch_datum( bcx, arg_ty, "" ,
1723
+ unpack_datum ! ( bcx, datum:: lvalue_scratch_datum( bcx, arg_ty, "" , uninit_reason ,
1673
1724
arg_scope_id, ( data, extra) ,
1674
1725
|( data, extra) , bcx, dst| {
1675
1726
Store ( bcx, data, expr:: get_dataptr( bcx, dst) ) ;
@@ -1684,6 +1735,7 @@ pub fn create_datums_for_fn_args<'a, 'tcx>(mut bcx: Block<'a, 'tcx>,
1684
1735
datum:: lvalue_scratch_datum( bcx,
1685
1736
arg_ty,
1686
1737
"" ,
1738
+ uninit_reason,
1687
1739
arg_scope_id,
1688
1740
tmp,
1689
1741
|tmp, bcx, dst| tmp. store_to( bcx, dst) ) )
@@ -1696,6 +1748,7 @@ pub fn create_datums_for_fn_args<'a, 'tcx>(mut bcx: Block<'a, 'tcx>,
1696
1748
datum:: lvalue_scratch_datum( bcx,
1697
1749
arg_ty,
1698
1750
"tupled_args" ,
1751
+ uninit_reason,
1699
1752
arg_scope_id,
1700
1753
( ) ,
1701
1754
|( ) ,
0 commit comments