Check for calls to functions with #[target_feature]
in THIR unsafeck
This commit is contained in:
parent
27fe959c2c
commit
d7787bbaef
9 changed files with 180 additions and 48 deletions
|
@ -7,6 +7,7 @@ use rustc_middle::ty::{self, TyCtxt};
|
|||
use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
|
||||
use rustc_session::lint::Level;
|
||||
use rustc_span::def_id::{DefId, LocalDefId};
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::Span;
|
||||
|
||||
struct UnsafetyVisitor<'a, 'tcx> {
|
||||
|
@ -19,6 +20,9 @@ struct UnsafetyVisitor<'a, 'tcx> {
|
|||
/// `unsafe` block, and whether it has been used.
|
||||
safety_context: SafetyContext,
|
||||
body_unsafety: BodyUnsafety,
|
||||
/// The `#[target_feature]` attributes of the body. Used for checking
|
||||
/// calls to functions with `#[target_feature]` (RFC 2396).
|
||||
body_target_features: &'tcx Vec<Symbol>,
|
||||
}
|
||||
|
||||
impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
|
||||
|
@ -148,6 +152,18 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
ExprKind::Call { fun, ty: _, args: _, from_hir_call: _, fn_span: _ } => {
|
||||
if self.thir[fun].ty.fn_sig(self.tcx).unsafety() == hir::Unsafety::Unsafe {
|
||||
self.requires_unsafe(expr.span, CallToUnsafeFunction);
|
||||
} else if let &ty::FnDef(func_did, _) = self.thir[fun].ty.kind() {
|
||||
// If the called function has target features the calling function hasn't,
|
||||
// the call requires `unsafe`.
|
||||
if !self
|
||||
.tcx
|
||||
.codegen_fn_attrs(func_did)
|
||||
.target_features
|
||||
.iter()
|
||||
.all(|feature| self.body_target_features.contains(feature))
|
||||
{
|
||||
self.requires_unsafe(expr.span, CallToFunctionWith);
|
||||
}
|
||||
}
|
||||
}
|
||||
ExprKind::InlineAsm { .. } | ExprKind::LlvmInlineAsm { .. } => {
|
||||
|
@ -217,7 +233,6 @@ enum UnsafeOpKind {
|
|||
MutationOfLayoutConstrainedField,
|
||||
#[allow(dead_code)] // FIXME
|
||||
BorrowOfLayoutConstrainedField,
|
||||
#[allow(dead_code)] // FIXME
|
||||
CallToFunctionWith,
|
||||
}
|
||||
|
||||
|
@ -291,6 +306,7 @@ pub fn check_unsafety<'tcx>(
|
|||
tcx: TyCtxt<'tcx>,
|
||||
thir: &Thir<'tcx>,
|
||||
expr: ExprId,
|
||||
def_id: LocalDefId,
|
||||
hir_id: hir::HirId,
|
||||
) {
|
||||
let body_unsafety = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(BodyUnsafety::Safe, |fn_sig| {
|
||||
|
@ -300,10 +316,17 @@ pub fn check_unsafety<'tcx>(
|
|||
BodyUnsafety::Safe
|
||||
}
|
||||
});
|
||||
let body_target_features = &tcx.codegen_fn_attrs(def_id).target_features;
|
||||
let safety_context =
|
||||
if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
|
||||
let mut visitor =
|
||||
UnsafetyVisitor { tcx, thir, safety_context, hir_context: hir_id, body_unsafety };
|
||||
let mut visitor = UnsafetyVisitor {
|
||||
tcx,
|
||||
thir,
|
||||
safety_context,
|
||||
hir_context: hir_id,
|
||||
body_unsafety,
|
||||
body_target_features,
|
||||
};
|
||||
visitor.visit_expr(&thir[expr]);
|
||||
}
|
||||
|
||||
|
@ -315,7 +338,7 @@ crate fn thir_check_unsafety_inner<'tcx>(
|
|||
let body_id = tcx.hir().body_owned_by(hir_id);
|
||||
let body = tcx.hir().body(body_id);
|
||||
let (thir, expr) = cx::build_thir(tcx, def, &body.value);
|
||||
check_unsafety(tcx, &thir, expr, hir_id);
|
||||
check_unsafety(tcx, &thir, expr, def.did, hir_id);
|
||||
}
|
||||
|
||||
crate fn thir_check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
// check-pass
|
||||
// only-x86_64
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
|
||||
#![feature(target_feature_11)]
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Tests #73631: closures inherit `#[target_feature]` annotations
|
||||
|
||||
// check-pass
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
// only-x86_64
|
||||
|
||||
#![feature(target_feature_11)]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-ptr.rs:9:21
|
||||
--> $DIR/fn-ptr.rs:11:21
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ---------------------------------- `#[target_feature]` added here
|
|
@ -1,3 +1,5 @@
|
|||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
// only-x86_64
|
||||
|
||||
#![feature(target_feature_11)]
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-ptr.rs:11:21
|
||||
|
|
||||
LL | #[target_feature(enable = "sse2")]
|
||||
| ---------------------------------- `#[target_feature]` added here
|
||||
...
|
||||
LL | let foo: fn() = foo;
|
||||
| ---- ^^^ cannot coerce functions with `#[target_feature]` to safe function pointers
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected fn pointer `fn()`
|
||||
found fn item `fn() {foo}`
|
||||
= note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
|
@ -1,69 +1,69 @@
|
|||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:21:5
|
||||
|
|
||||
LL | sse2();
|
||||
| ^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:22:5
|
||||
|
|
||||
LL | avx_bmi2();
|
||||
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:23:5
|
||||
|
|
||||
LL | Quux.avx_bmi2();
|
||||
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:28:5
|
||||
|
|
||||
LL | avx_bmi2();
|
||||
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:29:5
|
||||
|
|
||||
LL | Quux.avx_bmi2();
|
||||
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:34:5
|
||||
|
|
||||
LL | sse2();
|
||||
| ^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:35:5
|
||||
--> $DIR/safe-calls.rs:24:5
|
||||
|
|
||||
LL | avx_bmi2();
|
||||
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:25:5
|
||||
|
|
||||
LL | Quux.avx_bmi2();
|
||||
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:30:5
|
||||
|
|
||||
LL | avx_bmi2();
|
||||
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:31:5
|
||||
|
|
||||
LL | Quux.avx_bmi2();
|
||||
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:36:5
|
||||
|
|
||||
LL | sse2();
|
||||
| ^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:37:5
|
||||
|
|
||||
LL | avx_bmi2();
|
||||
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:38:5
|
||||
|
|
||||
LL | Quux.avx_bmi2();
|
||||
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:42:5
|
||||
--> $DIR/safe-calls.rs:44:5
|
||||
|
|
||||
LL | sse2();
|
||||
| ^^^^^^ call to function with `#[target_feature]`
|
||||
|
@ -71,7 +71,7 @@ LL | sse2();
|
|||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:45:18
|
||||
--> $DIR/safe-calls.rs:47:18
|
||||
|
|
||||
LL | const name: () = sse2();
|
||||
| ^^^^^^ call to function with `#[target_feature]`
|
|
@ -1,3 +1,5 @@
|
|||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Z thir-unsafeck
|
||||
// only-x86_64
|
||||
|
||||
#![feature(target_feature_11)]
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:23:5
|
||||
|
|
||||
LL | sse2();
|
||||
| ^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:24:5
|
||||
|
|
||||
LL | avx_bmi2();
|
||||
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:25:5
|
||||
|
|
||||
LL | Quux.avx_bmi2();
|
||||
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:30:5
|
||||
|
|
||||
LL | avx_bmi2();
|
||||
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:31:5
|
||||
|
|
||||
LL | Quux.avx_bmi2();
|
||||
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:36:5
|
||||
|
|
||||
LL | sse2();
|
||||
| ^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:37:5
|
||||
|
|
||||
LL | avx_bmi2();
|
||||
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:38:5
|
||||
|
|
||||
LL | Quux.avx_bmi2();
|
||||
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:44:5
|
||||
|
|
||||
LL | sse2();
|
||||
| ^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||
--> $DIR/safe-calls.rs:47:18
|
||||
|
|
||||
LL | const name: () = sse2();
|
||||
| ^^^^^^ call to function with `#[target_feature]`
|
||||
|
|
||||
= note: can only be called if the required target features are available
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0133`.
|
Loading…
Add table
Reference in a new issue