1
Fork 0

Add hir::HeaderSafety to make follow up commits simpler

This commit is contained in:
Oli Scherer 2024-12-13 12:19:46 +00:00
parent e491caec14
commit a907c56a77
23 changed files with 101 additions and 40 deletions

View file

@ -478,19 +478,27 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
return; // don't visit the whole expression
}
ExprKind::Call { fun, ty: _, args: _, from_hir_call: _, fn_span: _ } => {
if self.thir[fun].ty.fn_sig(self.tcx).safety().is_unsafe() {
let func_id = if let ty::FnDef(func_id, _) = self.thir[fun].ty.kind() {
let fn_ty = self.thir[fun].ty;
let sig = fn_ty.fn_sig(self.tcx);
let (callee_features, safe_target_features): (&[_], _) = match fn_ty.kind() {
ty::FnDef(func_id, ..) => {
let cg_attrs = self.tcx.codegen_fn_attrs(func_id);
(&cg_attrs.target_features, cg_attrs.safe_target_features)
}
_ => (&[], false),
};
if sig.safety().is_unsafe() && !safe_target_features {
let func_id = if let ty::FnDef(func_id, _) = fn_ty.kind() {
Some(*func_id)
} else {
None
};
self.requires_unsafe(expr.span, CallToUnsafeFunction(func_id));
} else if let &ty::FnDef(func_did, _) = self.thir[fun].ty.kind() {
} else if let &ty::FnDef(func_did, _) = fn_ty.kind() {
// If the called function has target features the calling function hasn't,
// the call requires `unsafe`. Don't check this on wasm
// targets, though. For more information on wasm see the
// is_like_wasm check in hir_analysis/src/collect.rs
let callee_features = &self.tcx.codegen_fn_attrs(func_did).target_features;
if !self.tcx.sess.target.options.is_like_wasm
&& !callee_features.iter().all(|feature| {
self.body_target_features.iter().any(|f| f.name == feature.name)
@ -1111,7 +1119,12 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
let hir_id = tcx.local_def_id_to_hir_id(def);
let safety_context = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| {
if fn_sig.header.safety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe }
match fn_sig.header.safety {
hir::HeaderSafety::Normal(safety) => match safety {
hir::Safety::Unsafe => SafetyContext::UnsafeFn,
hir::Safety::Safe => SafetyContext::Safe,
},
}
});
let body_target_features = &tcx.body_codegen_attrs(def.to_def_id()).target_features;
let mut warnings = Vec::new();