@@ -80,6 +80,7 @@ fn clif_sig_from_fn_sig<'tcx>(
80
80
triple : & target_lexicon:: Triple ,
81
81
sig : FnSig < ' tcx > ,
82
82
is_vtable_fn : bool ,
83
+ requires_caller_location : bool ,
83
84
) -> Signature {
84
85
let abi = match sig. abi {
85
86
Abi :: System => {
@@ -125,7 +126,7 @@ fn clif_sig_from_fn_sig<'tcx>(
125
126
} )
126
127
. flatten ( ) ;
127
128
128
- let ( params, returns) = match get_pass_mode (
129
+ let ( mut params, returns) : ( Vec < _ > , Vec < _ > ) = match get_pass_mode (
129
130
tcx,
130
131
tcx. layout_of ( ParamEnv :: reveal_all ( ) . and ( output) ) . unwrap ( ) ,
131
132
) {
@@ -150,6 +151,10 @@ fn clif_sig_from_fn_sig<'tcx>(
150
151
}
151
152
} ;
152
153
154
+ if requires_caller_location {
155
+ params. push ( AbiParam :: new ( pointer_ty ( tcx) ) ) ;
156
+ }
157
+
153
158
Signature {
154
159
params,
155
160
returns,
@@ -169,7 +174,7 @@ pub fn get_function_name_and_sig<'tcx>(
169
174
if fn_sig. c_variadic && !support_vararg {
170
175
unimpl ! ( "Variadic function definitions are not yet supported" ) ;
171
176
}
172
- let sig = clif_sig_from_fn_sig ( tcx, triple, fn_sig, false ) ;
177
+ let sig = clif_sig_from_fn_sig ( tcx, triple, fn_sig, false , inst . def . requires_caller_location ( tcx ) ) ;
173
178
( tcx. symbol_name ( inst) . name . as_str ( ) . to_string ( ) , sig)
174
179
}
175
180
@@ -316,18 +321,24 @@ pub fn codegen_fn_prelude(fx: &mut FunctionCx<'_, '_, impl Backend>, start_ebb:
316
321
317
322
let mut params = Vec :: new ( ) ;
318
323
for ( i, arg_ty) in tupled_arg_tys. types ( ) . enumerate ( ) {
319
- let param = cvalue_for_param ( fx, start_ebb, local, Some ( i) , arg_ty) ;
324
+ let param = cvalue_for_param ( fx, start_ebb, Some ( local) , Some ( i) , arg_ty) ;
320
325
params. push ( param) ;
321
326
}
322
327
323
328
( local, ArgKind :: Spread ( params) , arg_ty)
324
329
} else {
325
- let param = cvalue_for_param ( fx, start_ebb, local, None , arg_ty) ;
330
+ let param = cvalue_for_param ( fx, start_ebb, Some ( local) , None , arg_ty) ;
326
331
( local, ArgKind :: Normal ( param) , arg_ty)
327
332
}
328
333
} )
329
334
. collect :: < Vec < ( Local , ArgKind , Ty ) > > ( ) ;
330
335
336
+ assert ! ( fx. caller_location. is_none( ) ) ;
337
+ if fx. instance . def . requires_caller_location ( fx. tcx ) {
338
+ // Store caller location for `#[track_caller]`.
339
+ fx. caller_location = Some ( cvalue_for_param ( fx, start_ebb, None , None , fx. tcx . caller_location_ty ( ) ) . unwrap ( ) ) ;
340
+ }
341
+
331
342
fx. bcx . switch_to_block ( start_ebb) ;
332
343
fx. bcx . ins ( ) . nop ( ) ;
333
344
@@ -403,10 +414,10 @@ pub fn codegen_fn_prelude(fx: &mut FunctionCx<'_, '_, impl Backend>, start_ebb:
403
414
404
415
pub fn codegen_terminator_call < ' tcx > (
405
416
fx : & mut FunctionCx < ' _ , ' tcx , impl Backend > ,
417
+ span : Span ,
406
418
func : & Operand < ' tcx > ,
407
419
args : & [ Operand < ' tcx > ] ,
408
420
destination : & Option < ( Place < ' tcx > , BasicBlock ) > ,
409
- span : Span ,
410
421
) {
411
422
let fn_ty = fx. monomorphize ( & func. ty ( fx. mir , fx. tcx ) ) ;
412
423
let sig = fx
@@ -472,6 +483,7 @@ pub fn codegen_terminator_call<'tcx>(
472
483
473
484
codegen_call_inner (
474
485
fx,
486
+ span,
475
487
Some ( func) ,
476
488
fn_ty,
477
489
args,
@@ -488,6 +500,7 @@ pub fn codegen_terminator_call<'tcx>(
488
500
489
501
fn codegen_call_inner < ' tcx > (
490
502
fx : & mut FunctionCx < ' _ , ' tcx , impl Backend > ,
503
+ span : Span ,
491
504
func : Option < & Operand < ' tcx > > ,
492
505
fn_ty : Ty < ' tcx > ,
493
506
args : Vec < CValue < ' tcx > > ,
@@ -558,7 +571,7 @@ fn codegen_call_inner<'tcx>(
558
571
559
572
let ( call_inst, call_args) =
560
573
self :: returning:: codegen_with_call_return_arg ( fx, fn_sig, ret_place, |fx, return_ptr| {
561
- let call_args: Vec < Value > = return_ptr
574
+ let mut call_args: Vec < Value > = return_ptr
562
575
. into_iter ( )
563
576
. chain ( first_arg. into_iter ( ) )
564
577
. chain (
@@ -569,9 +582,20 @@ fn codegen_call_inner<'tcx>(
569
582
)
570
583
. collect :: < Vec < _ > > ( ) ;
571
584
585
+ if instance. map ( |inst| inst. def . requires_caller_location ( fx. tcx ) ) . unwrap_or ( false ) {
586
+ // Pass the caller location for `#[track_caller]`.
587
+ let caller_location = fx. get_caller_location ( span) ;
588
+ call_args. extend ( adjust_arg_for_abi ( fx, caller_location) . into_iter ( ) ) ;
589
+ }
590
+
572
591
let call_inst = if let Some ( func_ref) = func_ref {
573
- let sig =
574
- clif_sig_from_fn_sig ( fx. tcx , fx. triple ( ) , fn_sig, is_virtual_call) ;
592
+ let sig = clif_sig_from_fn_sig (
593
+ fx. tcx ,
594
+ fx. triple ( ) ,
595
+ fn_sig,
596
+ is_virtual_call,
597
+ false , // calls through function pointers never pass the caller location
598
+ ) ;
575
599
let sig = fx. bcx . import_signature ( sig) ;
576
600
fx. bcx . ins ( ) . call_indirect ( sig, func_ref, & call_args)
577
601
} else {
@@ -604,7 +628,11 @@ fn codegen_call_inner<'tcx>(
604
628
}
605
629
}
606
630
607
- pub fn codegen_drop < ' tcx > ( fx : & mut FunctionCx < ' _ , ' tcx , impl Backend > , drop_place : CPlace < ' tcx > ) {
631
+ pub fn codegen_drop < ' tcx > (
632
+ fx : & mut FunctionCx < ' _ , ' tcx , impl Backend > ,
633
+ span : Span ,
634
+ drop_place : CPlace < ' tcx > ,
635
+ ) {
608
636
let ty = drop_place. layout ( ) . ty ;
609
637
let drop_fn = Instance :: resolve_drop_in_place ( fx. tcx , ty) ;
610
638
@@ -625,7 +653,13 @@ pub fn codegen_drop<'tcx>(fx: &mut FunctionCx<'_, 'tcx, impl Backend>, drop_plac
625
653
626
654
assert_eq ! ( fn_sig. output( ) , fx. tcx. mk_unit( ) ) ;
627
655
628
- let sig = clif_sig_from_fn_sig ( fx. tcx , fx. triple ( ) , fn_sig, true ) ;
656
+ let sig = clif_sig_from_fn_sig (
657
+ fx. tcx ,
658
+ fx. triple ( ) ,
659
+ fn_sig,
660
+ true ,
661
+ false , // `drop_in_place` is never `#[track_caller]`
662
+ ) ;
629
663
let sig = fx. bcx . import_signature ( sig) ;
630
664
fx. bcx . ins ( ) . call_indirect ( sig, drop_fn, & [ ptr] ) ;
631
665
}
@@ -642,7 +676,7 @@ pub fn codegen_drop<'tcx>(fx: &mut FunctionCx<'_, 'tcx, impl Backend>, drop_plac
642
676
) ;
643
677
drop_place. write_place_ref ( fx, arg_place) ;
644
678
let arg_value = arg_place. to_cvalue ( fx) ;
645
- codegen_call_inner ( fx, None , drop_fn_ty, vec ! [ arg_value] , None ) ;
679
+ codegen_call_inner ( fx, span , None , drop_fn_ty, vec ! [ arg_value] , None ) ;
646
680
}
647
681
}
648
682
}
0 commit comments