@@ -478,19 +478,27 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
478478 return ; // don't visit the whole expression
479479 }
480480 ExprKind :: Call { fun, ty : _, args : _, from_hir_call : _, fn_span : _ } => {
481- if self . thir [ fun] . ty . fn_sig ( self . tcx ) . safety ( ) . is_unsafe ( ) {
482- let func_id = if let ty:: FnDef ( func_id, _) = self . thir [ fun] . ty . kind ( ) {
481+ let fn_ty = self . thir [ fun] . ty ;
482+ let sig = fn_ty. fn_sig ( self . tcx ) ;
483+ let ( callee_features, safe_target_features) : ( & [ _ ] , _ ) = match fn_ty. kind ( ) {
484+ ty:: FnDef ( func_id, ..) => {
485+ let cg_attrs = self . tcx . codegen_fn_attrs ( func_id) ;
486+ ( & cg_attrs. target_features , cg_attrs. safe_target_features )
487+ }
488+ _ => ( & [ ] , false ) ,
489+ } ;
490+ if sig. safety ( ) . is_unsafe ( ) && !safe_target_features {
491+ let func_id = if let ty:: FnDef ( func_id, _) = fn_ty. kind ( ) {
483492 Some ( * func_id)
484493 } else {
485494 None
486495 } ;
487496 self . requires_unsafe ( expr. span , CallToUnsafeFunction ( func_id) ) ;
488- } else if let & ty:: FnDef ( func_did, _) = self . thir [ fun ] . ty . kind ( ) {
497+ } else if let & ty:: FnDef ( func_did, _) = fn_ty . kind ( ) {
489498 // If the called function has target features the calling function hasn't,
490499 // the call requires `unsafe`. Don't check this on wasm
491500 // targets, though. For more information on wasm see the
492501 // is_like_wasm check in hir_analysis/src/collect.rs
493- let callee_features = & self . tcx . codegen_fn_attrs ( func_did) . target_features ;
494502 if !self . tcx . sess . target . options . is_like_wasm
495503 && !callee_features. iter ( ) . all ( |feature| {
496504 self . body_target_features . iter ( ) . any ( |f| f. name == feature. name )
@@ -1111,7 +1119,12 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
11111119
11121120 let hir_id = tcx. local_def_id_to_hir_id ( def) ;
11131121 let safety_context = tcx. hir ( ) . fn_sig_by_hir_id ( hir_id) . map_or ( SafetyContext :: Safe , |fn_sig| {
1114- if fn_sig. header . safety . is_unsafe ( ) { SafetyContext :: UnsafeFn } else { SafetyContext :: Safe }
1122+ match fn_sig. header . safety {
1123+ hir:: HeaderSafety :: Normal ( safety) => match safety {
1124+ hir:: Safety :: Unsafe => SafetyContext :: UnsafeFn ,
1125+ hir:: Safety :: Safe => SafetyContext :: Safe ,
1126+ } ,
1127+ }
11151128 } ) ;
11161129 let body_target_features = & tcx. body_codegen_attrs ( def. to_def_id ( ) ) . target_features ;
11171130 let mut warnings = Vec :: new ( ) ;
0 commit comments