mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-12-18 00:53:31 +00:00
Don't assume paths work with fn_sig
in multiple_unsafe_ops_pre_block
.
This commit is contained in:
parent
3d193fa17a
commit
002e934189
3 changed files with 99 additions and 28 deletions
|
@ -11,6 +11,7 @@ use rustc_ast::Mutability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
|
use rustc_middle::ty;
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
|
@ -120,35 +121,17 @@ fn collect_unsafe_exprs<'tcx>(
|
||||||
unsafe_ops.push(("raw pointer dereference occurs here", expr.span));
|
unsafe_ops.push(("raw pointer dereference occurs here", expr.span));
|
||||||
},
|
},
|
||||||
|
|
||||||
ExprKind::Call(path_expr, _) => match path_expr.kind {
|
ExprKind::Call(path_expr, _) => {
|
||||||
ExprKind::Path(QPath::Resolved(
|
let sig = match *cx.typeck_results().expr_ty(path_expr).kind() {
|
||||||
_,
|
ty::FnDef(id, _) => cx.tcx.fn_sig(id).skip_binder(),
|
||||||
hir::Path {
|
ty::FnPtr(sig) => sig,
|
||||||
res: Res::Def(kind, def_id),
|
_ => return Continue(Descend::Yes),
|
||||||
..
|
};
|
||||||
},
|
if sig.unsafety() == Unsafety::Unsafe {
|
||||||
)) if kind.is_fn_like() => {
|
|
||||||
let sig = cx.tcx.fn_sig(*def_id);
|
|
||||||
if sig.0.unsafety() == Unsafety::Unsafe {
|
|
||||||
unsafe_ops.push(("unsafe function call occurs here", expr.span));
|
unsafe_ops.push(("unsafe function call occurs here", expr.span));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
ExprKind::Path(QPath::TypeRelative(..)) => {
|
|
||||||
if let Some(sig) = cx
|
|
||||||
.typeck_results()
|
|
||||||
.type_dependent_def_id(path_expr.hir_id)
|
|
||||||
.map(|def_id| cx.tcx.fn_sig(def_id))
|
|
||||||
{
|
|
||||||
if sig.0.unsafety() == Unsafety::Unsafe {
|
|
||||||
unsafe_ops.push(("unsafe function call occurs here", expr.span));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_ => {},
|
|
||||||
},
|
|
||||||
|
|
||||||
ExprKind::MethodCall(..) => {
|
ExprKind::MethodCall(..) => {
|
||||||
if let Some(sig) = cx
|
if let Some(sig) = cx
|
||||||
.typeck_results()
|
.typeck_results()
|
||||||
|
|
|
@ -116,4 +116,32 @@ fn issue10259() {
|
||||||
unsafe_macro!();
|
unsafe_macro!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn _fn_ptr(x: unsafe fn()) {
|
||||||
|
unsafe {
|
||||||
|
x();
|
||||||
|
x();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _assoc_const() {
|
||||||
|
trait X {
|
||||||
|
const X: unsafe fn();
|
||||||
|
}
|
||||||
|
fn _f<T: X>() {
|
||||||
|
unsafe {
|
||||||
|
T::X();
|
||||||
|
T::X();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _field_fn_ptr(x: unsafe fn()) {
|
||||||
|
struct X(unsafe fn());
|
||||||
|
let x = X(x);
|
||||||
|
unsafe {
|
||||||
|
x.0();
|
||||||
|
x.0();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -125,5 +125,65 @@ note: raw pointer dereference occurs here
|
||||||
LL | unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }
|
LL | unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: this `unsafe` block contains 2 unsafe operations, expected only one
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:120:5
|
||||||
|
|
|
||||||
|
LL | / unsafe {
|
||||||
|
LL | | x();
|
||||||
|
LL | | x();
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
|
||||||
|
note: unsafe function call occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:121:9
|
||||||
|
|
|
||||||
|
LL | x();
|
||||||
|
| ^^^
|
||||||
|
note: unsafe function call occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:122:9
|
||||||
|
|
|
||||||
|
LL | x();
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: this `unsafe` block contains 2 unsafe operations, expected only one
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:131:9
|
||||||
|
|
|
||||||
|
LL | / unsafe {
|
||||||
|
LL | | T::X();
|
||||||
|
LL | | T::X();
|
||||||
|
LL | | }
|
||||||
|
| |_________^
|
||||||
|
|
|
||||||
|
note: unsafe function call occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:132:13
|
||||||
|
|
|
||||||
|
LL | T::X();
|
||||||
|
| ^^^^^^
|
||||||
|
note: unsafe function call occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:133:13
|
||||||
|
|
|
||||||
|
LL | T::X();
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: this `unsafe` block contains 2 unsafe operations, expected only one
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:141:5
|
||||||
|
|
|
||||||
|
LL | / unsafe {
|
||||||
|
LL | | x.0();
|
||||||
|
LL | | x.0();
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
|
|
||||||
|
note: unsafe function call occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:142:9
|
||||||
|
|
|
||||||
|
LL | x.0();
|
||||||
|
| ^^^^^
|
||||||
|
note: unsafe function call occurs here
|
||||||
|
--> $DIR/multiple_unsafe_ops_per_block.rs:143:9
|
||||||
|
|
|
||||||
|
LL | x.0();
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue