@@ -5,6 +5,7 @@ use super::{CachedLlbb, FunctionCx, LocalRef};
5
5
6
6
use crate :: base;
7
7
use crate :: common:: { self , IntPredicate } ;
8
+ use crate :: errors:: CompilerBuiltinsCannotCall ;
8
9
use crate :: meth;
9
10
use crate :: traits:: * ;
10
11
use crate :: MemFlags ;
@@ -16,7 +17,9 @@ use rustc_middle::mir::{self, AssertKind, BasicBlock, SwitchTargets, UnwindTermi
16
17
use rustc_middle:: ty:: layout:: { HasTyCtxt , LayoutOf , ValidityRequirement } ;
17
18
use rustc_middle:: ty:: print:: { with_no_trimmed_paths, with_no_visible_paths} ;
18
19
use rustc_middle:: ty:: { self , Instance , Ty } ;
20
+ use rustc_monomorphize:: should_codegen_locally;
19
21
use rustc_session:: config:: OptLevel ;
22
+ use rustc_span:: def_id:: LOCAL_CRATE ;
20
23
use rustc_span:: { source_map:: Spanned , sym, Span } ;
21
24
use rustc_target:: abi:: call:: { ArgAbi , FnAbi , PassMode , Reg } ;
22
25
use rustc_target:: abi:: { self , HasDataLayout , WrappingRange } ;
@@ -157,8 +160,31 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
157
160
destination : Option < ( ReturnDest < ' tcx , Bx :: Value > , mir:: BasicBlock ) > ,
158
161
mut unwind : mir:: UnwindAction ,
159
162
copied_constant_arguments : & [ PlaceRef < ' tcx , <Bx as BackendTypes >:: Value > ] ,
163
+ instance : Option < Instance < ' tcx > > ,
160
164
mergeable_succ : bool ,
161
165
) -> MergingSucc {
166
+ let tcx = bx. tcx ( ) ;
167
+ if let Some ( instance) = instance {
168
+ let def_id = instance. def_id ( ) ;
169
+ if !def_id. is_local ( )
170
+ && tcx. is_compiler_builtins ( LOCAL_CRATE )
171
+ && !should_codegen_locally ( tcx, & instance)
172
+ {
173
+ if destination. is_some ( ) {
174
+ let callee = with_no_trimmed_paths ! ( tcx. def_path_str( def_id) ) ;
175
+ tcx. dcx ( ) . emit_err ( CompilerBuiltinsCannotCall { callee } ) ;
176
+ } else {
177
+ info ! (
178
+ "compiler_builtins call to diverging function {:?} replaced with abort" ,
179
+ instance. def_id( )
180
+ ) ;
181
+ bx. abort ( ) ;
182
+ bx. unreachable ( ) ;
183
+ return MergingSucc :: False ;
184
+ }
185
+ }
186
+ }
187
+
162
188
// If there is a cleanup block and the function we're calling can unwind, then
163
189
// do an invoke, otherwise do a call.
164
190
let fn_ty = bx. fn_decl_backend_type ( fn_abi) ;
@@ -480,6 +506,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
480
506
let ty = location. ty ( self . mir , bx. tcx ( ) ) . ty ;
481
507
let ty = self . monomorphize ( ty) ;
482
508
let drop_fn = Instance :: resolve_drop_in_place ( bx. tcx ( ) , ty) ;
509
+ let instance = drop_fn. clone ( ) ;
483
510
484
511
if let ty:: InstanceDef :: DropGlue ( _, None ) = drop_fn. def {
485
512
// we don't actually need to drop anything.
@@ -582,6 +609,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
582
609
Some ( ( ReturnDest :: Nothing , target) ) ,
583
610
unwind,
584
611
& [ ] ,
612
+ Some ( instance) ,
585
613
mergeable_succ,
586
614
)
587
615
}
@@ -658,10 +686,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
658
686
}
659
687
} ;
660
688
661
- let ( fn_abi, llfn) = common:: build_langcall ( bx, Some ( span) , lang_item) ;
689
+ let ( fn_abi, llfn, instance ) = common:: build_langcall ( bx, Some ( span) , lang_item) ;
662
690
663
691
// Codegen the actual panic invoke/call.
664
- let merging_succ = helper. do_call ( self , bx, fn_abi, llfn, & args, None , unwind, & [ ] , false ) ;
692
+ let merging_succ =
693
+ helper. do_call ( self , bx, fn_abi, llfn, & args, None , unwind, & [ ] , Some ( instance) , false ) ;
665
694
assert_eq ! ( merging_succ, MergingSucc :: False ) ;
666
695
MergingSucc :: False
667
696
}
@@ -677,7 +706,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
677
706
self . set_debug_loc ( bx, terminator. source_info ) ;
678
707
679
708
// Obtain the panic entry point.
680
- let ( fn_abi, llfn) = common:: build_langcall ( bx, Some ( span) , reason. lang_item ( ) ) ;
709
+ let ( fn_abi, llfn, instance ) = common:: build_langcall ( bx, Some ( span) , reason. lang_item ( ) ) ;
681
710
682
711
// Codegen the actual panic invoke/call.
683
712
let merging_succ = helper. do_call (
@@ -689,6 +718,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
689
718
None ,
690
719
mir:: UnwindAction :: Unreachable ,
691
720
& [ ] ,
721
+ Some ( instance) ,
692
722
false ,
693
723
) ;
694
724
assert_eq ! ( merging_succ, MergingSucc :: False ) ;
@@ -738,7 +768,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
738
768
let msg = bx. const_str ( & msg_str) ;
739
769
740
770
// Obtain the panic entry point.
741
- let ( fn_abi, llfn) =
771
+ let ( fn_abi, llfn, instance ) =
742
772
common:: build_langcall ( bx, Some ( source_info. span ) , LangItem :: PanicNounwind ) ;
743
773
744
774
// Codegen the actual panic invoke/call.
@@ -751,6 +781,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
751
781
target. as_ref ( ) . map ( |bb| ( ReturnDest :: Nothing , * bb) ) ,
752
782
unwind,
753
783
& [ ] ,
784
+ Some ( instance) ,
754
785
mergeable_succ,
755
786
)
756
787
} else {
@@ -798,6 +829,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
798
829
ty:: FnPtr ( _) => ( None , Some ( callee. immediate ( ) ) ) ,
799
830
_ => bug ! ( "{} is not callable" , callee. layout. ty) ,
800
831
} ;
832
+
801
833
let def = instance. map ( |i| i. def ) ;
802
834
803
835
if let Some ( ty:: InstanceDef :: DropGlue ( _, None ) ) = def {
@@ -1106,6 +1138,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
1106
1138
destination,
1107
1139
unwind,
1108
1140
& copied_constant_arguments,
1141
+ instance,
1109
1142
mergeable_succ,
1110
1143
)
1111
1144
}
@@ -1664,7 +1697,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
1664
1697
1665
1698
self . set_debug_loc ( & mut bx, mir:: SourceInfo :: outermost ( self . mir . span ) ) ;
1666
1699
1667
- let ( fn_abi, fn_ptr) = common:: build_langcall ( & bx, None , reason. lang_item ( ) ) ;
1700
+ let ( fn_abi, fn_ptr, _instance ) = common:: build_langcall ( & bx, None , reason. lang_item ( ) ) ;
1668
1701
let fn_ty = bx. fn_decl_backend_type ( fn_abi) ;
1669
1702
1670
1703
let llret = bx. call ( fn_ty, None , Some ( fn_abi) , fn_ptr, & [ ] , funclet. as_ref ( ) ) ;
0 commit comments