@@ -5,6 +5,7 @@ use super::{CachedLlbb, FunctionCx, LocalRef};
55
66use crate :: base;
77use crate :: common:: { self , IntPredicate } ;
8+ use crate :: errors:: CompilerBuiltinsCannotCall ;
89use crate :: meth;
910use crate :: traits:: * ;
1011use crate :: MemFlags ;
@@ -16,6 +17,7 @@ use rustc_middle::mir::{self, AssertKind, BasicBlock, SwitchTargets, UnwindTermi
1617use rustc_middle:: ty:: layout:: { HasTyCtxt , LayoutOf , ValidityRequirement } ;
1718use rustc_middle:: ty:: print:: { with_no_trimmed_paths, with_no_visible_paths} ;
1819use rustc_middle:: ty:: { self , Instance , Ty } ;
20+ use rustc_monomorphize:: is_call_from_compiler_builtins_to_upstream_monomorphization;
1921use rustc_session:: config:: OptLevel ;
2022use rustc_span:: { source_map:: Spanned , sym, Span } ;
2123use rustc_target:: abi:: call:: { ArgAbi , FnAbi , PassMode , Reg } ;
@@ -157,8 +159,28 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
157159 destination : Option < ( ReturnDest < ' tcx , Bx :: Value > , mir:: BasicBlock ) > ,
158160 mut unwind : mir:: UnwindAction ,
159161 copied_constant_arguments : & [ PlaceRef < ' tcx , <Bx as BackendTypes >:: Value > ] ,
162+ instance : Option < Instance < ' tcx > > ,
160163 mergeable_succ : bool ,
161164 ) -> MergingSucc {
165+ let tcx = bx. tcx ( ) ;
166+ if let Some ( instance) = instance {
167+ if is_call_from_compiler_builtins_to_upstream_monomorphization ( tcx, instance) {
168+ if destination. is_some ( ) {
169+ let caller = with_no_trimmed_paths ! ( tcx. def_path_str( fx. instance. def_id( ) ) ) ;
170+ let callee = with_no_trimmed_paths ! ( tcx. def_path_str( instance. def_id( ) ) ) ;
171+ tcx. dcx ( ) . emit_err ( CompilerBuiltinsCannotCall { caller, callee } ) ;
172+ } else {
173+ info ! (
174+ "compiler_builtins call to diverging function {:?} replaced with abort" ,
175+ instance. def_id( )
176+ ) ;
177+ bx. abort ( ) ;
178+ bx. unreachable ( ) ;
179+ return MergingSucc :: False ;
180+ }
181+ }
182+ }
183+
162184 // If there is a cleanup block and the function we're calling can unwind, then
163185 // do an invoke, otherwise do a call.
164186 let fn_ty = bx. fn_decl_backend_type ( fn_abi) ;
@@ -480,6 +502,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
480502 let ty = location. ty ( self . mir , bx. tcx ( ) ) . ty ;
481503 let ty = self . monomorphize ( ty) ;
482504 let drop_fn = Instance :: resolve_drop_in_place ( bx. tcx ( ) , ty) ;
505+ let instance = drop_fn. clone ( ) ;
483506
484507 if let ty:: InstanceDef :: DropGlue ( _, None ) = drop_fn. def {
485508 // we don't actually need to drop anything.
@@ -582,6 +605,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
582605 Some ( ( ReturnDest :: Nothing , target) ) ,
583606 unwind,
584607 & [ ] ,
608+ Some ( instance) ,
585609 mergeable_succ,
586610 )
587611 }
@@ -658,10 +682,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
658682 }
659683 } ;
660684
661- let ( fn_abi, llfn) = common:: build_langcall ( bx, Some ( span) , lang_item) ;
685+ let ( fn_abi, llfn, instance ) = common:: build_langcall ( bx, Some ( span) , lang_item) ;
662686
663687 // Codegen the actual panic invoke/call.
664- let merging_succ = helper. do_call ( self , bx, fn_abi, llfn, & args, None , unwind, & [ ] , false ) ;
688+ let merging_succ =
689+ helper. do_call ( self , bx, fn_abi, llfn, & args, None , unwind, & [ ] , Some ( instance) , false ) ;
665690 assert_eq ! ( merging_succ, MergingSucc :: False ) ;
666691 MergingSucc :: False
667692 }
@@ -677,7 +702,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
677702 self . set_debug_loc ( bx, terminator. source_info ) ;
678703
679704 // Obtain the panic entry point.
680- let ( fn_abi, llfn) = common:: build_langcall ( bx, Some ( span) , reason. lang_item ( ) ) ;
705+ let ( fn_abi, llfn, instance ) = common:: build_langcall ( bx, Some ( span) , reason. lang_item ( ) ) ;
681706
682707 // Codegen the actual panic invoke/call.
683708 let merging_succ = helper. do_call (
@@ -689,6 +714,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
689714 None ,
690715 mir:: UnwindAction :: Unreachable ,
691716 & [ ] ,
717+ Some ( instance) ,
692718 false ,
693719 ) ;
694720 assert_eq ! ( merging_succ, MergingSucc :: False ) ;
@@ -738,7 +764,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
738764 let msg = bx. const_str ( & msg_str) ;
739765
740766 // Obtain the panic entry point.
741- let ( fn_abi, llfn) =
767+ let ( fn_abi, llfn, instance ) =
742768 common:: build_langcall ( bx, Some ( source_info. span ) , LangItem :: PanicNounwind ) ;
743769
744770 // Codegen the actual panic invoke/call.
@@ -751,6 +777,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
751777 target. as_ref ( ) . map ( |bb| ( ReturnDest :: Nothing , * bb) ) ,
752778 unwind,
753779 & [ ] ,
780+ Some ( instance) ,
754781 mergeable_succ,
755782 )
756783 } else {
@@ -798,6 +825,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
798825 ty:: FnPtr ( _) => ( None , Some ( callee. immediate ( ) ) ) ,
799826 _ => bug ! ( "{} is not callable" , callee. layout. ty) ,
800827 } ;
828+
801829 let def = instance. map ( |i| i. def ) ;
802830
803831 if let Some ( ty:: InstanceDef :: DropGlue ( _, None ) ) = def {
@@ -1106,6 +1134,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11061134 destination,
11071135 unwind,
11081136 & copied_constant_arguments,
1137+ instance,
11091138 mergeable_succ,
11101139 )
11111140 }
@@ -1664,7 +1693,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
16641693
16651694 self . set_debug_loc ( & mut bx, mir:: SourceInfo :: outermost ( self . mir . span ) ) ;
16661695
1667- let ( fn_abi, fn_ptr) = common:: build_langcall ( & bx, None , reason. lang_item ( ) ) ;
1696+ let ( fn_abi, fn_ptr, _instance ) = common:: build_langcall ( & bx, None , reason. lang_item ( ) ) ;
16681697 let fn_ty = bx. fn_decl_backend_type ( fn_abi) ;
16691698
16701699 let llret = bx. call ( fn_ty, None , Some ( fn_abi) , fn_ptr, & [ ] , funclet. as_ref ( ) ) ;
0 commit comments