Skip to content

Commit

Permalink
Auto merge of rust-lang#10405 - Jarcho:issue_10367, r=flip1995
Browse files Browse the repository at this point in the history
Fix ICE in `multiple_unsafe_ops_per_block`

fixes rust-lang#10367

changelog: [`multiple_unsafe_ops_per_block`]: Fix ICE when calling a function-like object in an unsafe block
  • Loading branch information
bors committed Feb 28, 2023
2 parents acf70ea + 002e934 commit 1a11ad7
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 28 deletions.
37 changes: 10 additions & 27 deletions clippy_lints/src/multiple_unsafe_ops_per_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use rustc_ast::Mutability;
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::Span;

Expand Down Expand Up @@ -120,33 +121,15 @@ fn collect_unsafe_exprs<'tcx>(
unsafe_ops.push(("raw pointer dereference occurs here", expr.span));
},

ExprKind::Call(path_expr, _) => match path_expr.kind {
ExprKind::Path(QPath::Resolved(
_,
hir::Path {
res: Res::Def(kind, def_id),
..
},
)) 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));
}
},

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::Call(path_expr, _) => {
let sig = match *cx.typeck_results().expr_ty(path_expr).kind() {
ty::FnDef(id, _) => cx.tcx.fn_sig(id).skip_binder(),
ty::FnPtr(sig) => sig,
_ => return Continue(Descend::Yes),
};
if sig.unsafety() == Unsafety::Unsafe {
unsafe_ops.push(("unsafe function call occurs here", expr.span));
}
},

ExprKind::MethodCall(..) => {
Expand Down
28 changes: 28 additions & 0 deletions tests/ui/multiple_unsafe_ops_per_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,32 @@ fn issue10259() {
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() {}
62 changes: 61 additions & 1 deletion tests/ui/multiple_unsafe_ops_per_block.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -125,5 +125,65 @@ note: raw pointer dereference occurs here
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

0 comments on commit 1a11ad7

Please sign in to comment.