@@ -478,19 +478,27 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
478
478
return ; // don't visit the whole expression
479
479
}
480
480
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 ( ) {
483
492
Some ( * func_id)
484
493
} else {
485
494
None
486
495
} ;
487
496
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 ( ) {
489
498
// If the called function has target features the calling function hasn't,
490
499
// the call requires `unsafe`. Don't check this on wasm
491
500
// targets, though. For more information on wasm see the
492
501
// is_like_wasm check in hir_analysis/src/collect.rs
493
- let callee_features = & self . tcx . codegen_fn_attrs ( func_did) . target_features ;
494
502
if !self . tcx . sess . target . options . is_like_wasm
495
503
&& !callee_features. iter ( ) . all ( |feature| {
496
504
self . body_target_features . iter ( ) . any ( |f| f. name == feature. name )
@@ -1111,7 +1119,12 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
1111
1119
1112
1120
let hir_id = tcx. local_def_id_to_hir_id ( def) ;
1113
1121
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
+ }
1115
1128
} ) ;
1116
1129
let body_target_features = & tcx. body_codegen_attrs ( def. to_def_id ( ) ) . target_features ;
1117
1130
let mut warnings = Vec :: new ( ) ;
0 commit comments