11use std:: cmp;
22
3- use rustc_abi:: { BackendRepr , ExternAbi , HasDataLayout , Reg , WrappingRange } ;
3+ use rustc_abi:: { BackendRepr , ExternAbi , HasDataLayout , Reg , Size , WrappingRange } ;
44use rustc_ast as ast;
55use rustc_ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
66use rustc_data_structures:: packed:: Pu128 ;
@@ -158,7 +158,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
158158 llargs : & [ Bx :: Value ] ,
159159 destination : Option < ( ReturnDest < ' tcx , Bx :: Value > , mir:: BasicBlock ) > ,
160160 mut unwind : mir:: UnwindAction ,
161- copied_constant_arguments : & [ PlaceRef < ' tcx , < Bx as BackendTypes > :: Value > ] ,
161+ lifetime_ends_after_call : & [ ( Bx :: Value , Size ) ] ,
162162 instance : Option < Instance < ' tcx > > ,
163163 mergeable_succ : bool ,
164164 ) -> MergingSucc {
@@ -245,8 +245,8 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
245245 if let Some ( ( ret_dest, target) ) = destination {
246246 bx. switch_to_block ( fx. llbb ( target) ) ;
247247 fx. set_debug_loc ( bx, self . terminator . source_info ) ;
248- for tmp in copied_constant_arguments {
249- bx. lifetime_end ( tmp. val . llval , tmp . layout . size ) ;
248+ for & ( tmp, size ) in lifetime_ends_after_call {
249+ bx. lifetime_end ( tmp, size) ;
250250 }
251251 fx. store_return ( bx, ret_dest, & fn_abi. ret , invokeret) ;
252252 }
@@ -259,8 +259,8 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
259259 }
260260
261261 if let Some ( ( ret_dest, target) ) = destination {
262- for tmp in copied_constant_arguments {
263- bx. lifetime_end ( tmp. val . llval , tmp . layout . size ) ;
262+ for & ( tmp, size ) in lifetime_ends_after_call {
263+ bx. lifetime_end ( tmp, size) ;
264264 }
265265 fx. store_return ( bx, ret_dest, & fn_abi. ret , llret) ;
266266 self . funclet_br ( fx, bx, target, mergeable_succ)
@@ -1049,7 +1049,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
10491049 ( args, None )
10501050 } ;
10511051
1052- let mut copied_constant_arguments = vec ! [ ] ;
1052+ // Keeps track of temporary allocas whose liftime need to be ended after the call.
1053+ let mut lifetime_ends_after_call: Vec < ( Bx :: Value , Size ) > = Vec :: new ( ) ;
10531054 ' make_args: for ( i, arg) in first_args. iter ( ) . enumerate ( ) {
10541055 let mut op = self . codegen_operand ( bx, & arg. node ) ;
10551056
@@ -1137,19 +1138,26 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11371138 bx. lifetime_start ( tmp. val . llval , tmp. layout . size ) ;
11381139 op. val . store ( bx, tmp) ;
11391140 op. val = Ref ( tmp. val ) ;
1140- copied_constant_arguments . push ( tmp) ;
1141+ lifetime_ends_after_call . push ( ( tmp. val . llval , tmp . layout . size ) ) ;
11411142 }
11421143 _ => { }
11431144 }
11441145
1145- self . codegen_argument ( bx, op, & mut llargs, & fn_abi. args [ i] ) ;
1146+ self . codegen_argument (
1147+ bx,
1148+ op,
1149+ & mut llargs,
1150+ & fn_abi. args [ i] ,
1151+ & mut lifetime_ends_after_call,
1152+ ) ;
11461153 }
11471154 let num_untupled = untuple. map ( |tup| {
11481155 self . codegen_arguments_untupled (
11491156 bx,
11501157 & tup. node ,
11511158 & mut llargs,
11521159 & fn_abi. args [ first_args. len ( ) ..] ,
1160+ & mut lifetime_ends_after_call,
11531161 )
11541162 } ) ;
11551163
@@ -1174,7 +1182,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11741182 ) ;
11751183
11761184 let last_arg = fn_abi. args . last ( ) . unwrap ( ) ;
1177- self . codegen_argument ( bx, location, & mut llargs, last_arg) ;
1185+ self . codegen_argument (
1186+ bx,
1187+ location,
1188+ & mut llargs,
1189+ last_arg,
1190+ & mut lifetime_ends_after_call,
1191+ ) ;
11781192 }
11791193
11801194 let fn_ptr = match ( instance, llfn) {
@@ -1190,7 +1204,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11901204 & llargs,
11911205 destination,
11921206 unwind,
1193- & copied_constant_arguments ,
1207+ & lifetime_ends_after_call ,
11941208 instance,
11951209 mergeable_succ,
11961210 )
@@ -1475,6 +1489,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
14751489 op : OperandRef < ' tcx , Bx :: Value > ,
14761490 llargs : & mut Vec < Bx :: Value > ,
14771491 arg : & ArgAbi < ' tcx , Ty < ' tcx > > ,
1492+ lifetime_ends_after_call : & mut Vec < ( Bx :: Value , Size ) > ,
14781493 ) {
14791494 match arg. mode {
14801495 PassMode :: Ignore => return ,
@@ -1513,7 +1528,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
15131528 None => arg. layout . align . abi ,
15141529 } ;
15151530 let scratch = PlaceValue :: alloca ( bx, arg. layout . size , required_align) ;
1531+ bx. lifetime_start ( scratch. llval , arg. layout . size ) ;
15161532 op. val . store ( bx, scratch. with_type ( arg. layout ) ) ;
1533+ lifetime_ends_after_call. push ( ( scratch. llval , arg. layout . size ) ) ;
15171534 ( scratch. llval , scratch. align , true )
15181535 }
15191536 PassMode :: Cast { .. } => {
@@ -1534,7 +1551,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
15341551 // alignment requirements may be higher than the type's alignment, so copy
15351552 // to a higher-aligned alloca.
15361553 let scratch = PlaceValue :: alloca ( bx, arg. layout . size , required_align) ;
1554+ bx. lifetime_start ( scratch. llval , arg. layout . size ) ;
15371555 bx. typed_place_copy ( scratch, op_place_val, op. layout ) ;
1556+ lifetime_ends_after_call. push ( ( scratch. llval , arg. layout . size ) ) ;
15381557 ( scratch. llval , scratch. align , true )
15391558 } else {
15401559 ( op_place_val. llval , op_place_val. align , true )
@@ -1616,6 +1635,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
16161635 operand : & mir:: Operand < ' tcx > ,
16171636 llargs : & mut Vec < Bx :: Value > ,
16181637 args : & [ ArgAbi < ' tcx , Ty < ' tcx > > ] ,
1638+ lifetime_ends_after_call : & mut Vec < ( Bx :: Value , Size ) > ,
16191639 ) -> usize {
16201640 let tuple = self . codegen_operand ( bx, operand) ;
16211641
@@ -1628,13 +1648,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
16281648 for i in 0 ..tuple. layout . fields . count ( ) {
16291649 let field_ptr = tuple_ptr. project_field ( bx, i) ;
16301650 let field = bx. load_operand ( field_ptr) ;
1631- self . codegen_argument ( bx, field, llargs, & args[ i] ) ;
1651+ self . codegen_argument ( bx, field, llargs, & args[ i] , lifetime_ends_after_call ) ;
16321652 }
16331653 } else {
16341654 // If the tuple is immediate, the elements are as well.
16351655 for i in 0 ..tuple. layout . fields . count ( ) {
16361656 let op = tuple. extract_field ( self , bx, i) ;
1637- self . codegen_argument ( bx, op, llargs, & args[ i] ) ;
1657+ self . codegen_argument ( bx, op, llargs, & args[ i] , lifetime_ends_after_call ) ;
16381658 }
16391659 }
16401660 tuple. layout . fields . count ( )
0 commit comments