@@ -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