Consider labels of inline asm as conditionally executed
Since an `asm!()` statement is mostly unknown, as we do not know what it does, consider all labels' `break` as being conditionally executed only.
This commit is contained in:
parent
25cbcb4331
commit
a5b3c445da
3 changed files with 94 additions and 43 deletions
|
|
@ -7,7 +7,7 @@ use clippy_utils::source::snippet;
|
|||
use clippy_utils::visitors::{Descend, for_each_expr_without_closures};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{
|
||||
Block, Destination, Expr, ExprKind, HirId, InlineAsmOperand, Node, Pat, Stmt, StmtKind, StructTailExpr,
|
||||
Block, Destination, Expr, ExprKind, HirId, InlineAsm, InlineAsmOperand, Node, Pat, Stmt, StmtKind, StructTailExpr,
|
||||
};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::{BytePos, Span, sym};
|
||||
|
|
@ -75,12 +75,19 @@ pub(super) fn check<'tcx>(
|
|||
fn contains_any_break_or_continue(block: &Block<'_>) -> bool {
|
||||
for_each_expr_without_closures(block, |e| match e.kind {
|
||||
ExprKind::Break(..) | ExprKind::Continue(..) => ControlFlow::Break(()),
|
||||
ExprKind::InlineAsm(asm) if contains_label(asm) => ControlFlow::Break(()),
|
||||
ExprKind::Loop(..) => ControlFlow::Continue(Descend::No),
|
||||
_ => ControlFlow::Continue(Descend::Yes),
|
||||
})
|
||||
.is_some()
|
||||
}
|
||||
|
||||
fn contains_label(asm: &InlineAsm<'_>) -> bool {
|
||||
asm.operands
|
||||
.iter()
|
||||
.any(|(op, _span)| matches!(op, InlineAsmOperand::Label { .. }))
|
||||
}
|
||||
|
||||
/// The `never_loop` analysis keeps track of three things:
|
||||
///
|
||||
/// * Has any (reachable) code path hit a `continue` of the main loop?
|
||||
|
|
@ -378,7 +385,15 @@ fn never_loop_expr<'tcx>(
|
|||
InlineAsmOperand::Const { .. } | InlineAsmOperand::SymFn { .. } | InlineAsmOperand::SymStatic { .. } => {
|
||||
NeverLoopResult::Normal
|
||||
},
|
||||
InlineAsmOperand::Label { block } => never_loop_block(cx, block, local_labels, main_loop_id),
|
||||
InlineAsmOperand::Label { block } =>
|
||||
// We do not know whether the label will be executed or not, so `Diverging` must be
|
||||
// downgraded to `Normal`.
|
||||
{
|
||||
match never_loop_block(cx, block, local_labels, main_loop_id) {
|
||||
NeverLoopResult::Diverging { .. } => NeverLoopResult::Normal,
|
||||
result => result,
|
||||
}
|
||||
},
|
||||
})),
|
||||
ExprKind::OffsetOf(_, _)
|
||||
| ExprKind::Yield(_, _)
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
#![feature(try_blocks)]
|
||||
#![allow(
|
||||
clippy::eq_op,
|
||||
clippy::single_match,
|
||||
unused_assignments,
|
||||
unused_variables,
|
||||
clippy::while_immutable_condition
|
||||
)]
|
||||
#![expect(clippy::eq_op, clippy::single_match, clippy::while_immutable_condition)]
|
||||
//@no-rustfix
|
||||
|
||||
use std::arch::asm;
|
||||
|
||||
fn test1() {
|
||||
let mut x = 0;
|
||||
loop {
|
||||
|
|
@ -522,3 +519,30 @@ fn issue15350() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn issue15673() {
|
||||
loop {
|
||||
unsafe {
|
||||
// No lint since we don't analyze the inside of the asm
|
||||
asm! {
|
||||
"/* {} */",
|
||||
label {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//~v never_loop
|
||||
loop {
|
||||
unsafe {
|
||||
asm! {
|
||||
"/* {} */",
|
||||
label {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:12:5
|
||||
--> tests/ui/never_loop.rs:9:5
|
||||
|
|
||||
LL | / loop {
|
||||
... |
|
||||
|
|
@ -10,7 +10,7 @@ LL | | }
|
|||
= note: `#[deny(clippy::never_loop)]` on by default
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:36:5
|
||||
--> tests/ui/never_loop.rs:33:5
|
||||
|
|
||||
LL | / loop {
|
||||
... |
|
||||
|
|
@ -19,7 +19,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:58:5
|
||||
--> tests/ui/never_loop.rs:55:5
|
||||
|
|
||||
LL | / loop {
|
||||
... |
|
||||
|
|
@ -28,7 +28,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:62:9
|
||||
--> tests/ui/never_loop.rs:59:9
|
||||
|
|
||||
LL | / while i == 0 {
|
||||
... |
|
||||
|
|
@ -36,7 +36,7 @@ LL | | }
|
|||
| |_________^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:76:9
|
||||
--> tests/ui/never_loop.rs:73:9
|
||||
|
|
||||
LL | / loop {
|
||||
... |
|
||||
|
|
@ -45,7 +45,7 @@ LL | | }
|
|||
| |_________^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:114:5
|
||||
--> tests/ui/never_loop.rs:111:5
|
||||
|
|
||||
LL | / while let Some(y) = x {
|
||||
... |
|
||||
|
|
@ -53,7 +53,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:123:5
|
||||
--> tests/ui/never_loop.rs:120:5
|
||||
|
|
||||
LL | / for x in 0..10 {
|
||||
... |
|
||||
|
|
@ -67,7 +67,7 @@ LL + if let Some(x) = (0..10).next() {
|
|||
|
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:173:5
|
||||
--> tests/ui/never_loop.rs:170:5
|
||||
|
|
||||
LL | / 'outer: while a {
|
||||
... |
|
||||
|
|
@ -76,7 +76,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:190:9
|
||||
--> tests/ui/never_loop.rs:187:9
|
||||
|
|
||||
LL | / while false {
|
||||
LL | |
|
||||
|
|
@ -86,7 +86,7 @@ LL | | }
|
|||
| |_________^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:243:13
|
||||
--> tests/ui/never_loop.rs:240:13
|
||||
|
|
||||
LL | let _ = loop {
|
||||
| _____________^
|
||||
|
|
@ -99,7 +99,7 @@ LL | | };
|
|||
| |_____^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:266:5
|
||||
--> tests/ui/never_loop.rs:263:5
|
||||
|
|
||||
LL | / 'a: loop {
|
||||
LL | |
|
||||
|
|
@ -110,7 +110,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: sub-expression diverges
|
||||
--> tests/ui/never_loop.rs:271:17
|
||||
--> tests/ui/never_loop.rs:268:17
|
||||
|
|
||||
LL | break 'a;
|
||||
| ^^^^^^^^
|
||||
|
|
@ -119,7 +119,7 @@ LL | break 'a;
|
|||
= help: to override `-D warnings` add `#[allow(clippy::diverging_sub_expression)]`
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:303:13
|
||||
--> tests/ui/never_loop.rs:300:13
|
||||
|
|
||||
LL | / for _ in 0..20 {
|
||||
LL | |
|
||||
|
|
@ -135,7 +135,7 @@ LL + if let Some(_) = (0..20).next() {
|
|||
|
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:388:13
|
||||
--> tests/ui/never_loop.rs:385:13
|
||||
|
|
||||
LL | / 'c: loop {
|
||||
LL | |
|
||||
|
|
@ -145,7 +145,7 @@ LL | | }
|
|||
| |_____________^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:400:5
|
||||
--> tests/ui/never_loop.rs:397:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -155,7 +155,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:405:5
|
||||
--> tests/ui/never_loop.rs:402:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -165,7 +165,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:426:5
|
||||
--> tests/ui/never_loop.rs:423:5
|
||||
|
|
||||
LL | / for v in 0..10 {
|
||||
LL | |
|
||||
|
|
@ -183,7 +183,7 @@ LL ~
|
|||
|
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:434:5
|
||||
--> tests/ui/never_loop.rs:431:5
|
||||
|
|
||||
LL | / 'outer: for v in 0..10 {
|
||||
LL | |
|
||||
|
|
@ -194,7 +194,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
|
||||
help: this code is unreachable. Consider moving the reachable parts out
|
||||
--> tests/ui/never_loop.rs:436:9
|
||||
--> tests/ui/never_loop.rs:433:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -202,7 +202,7 @@ LL | | break 'outer;
|
|||
LL | | }
|
||||
| |_________^
|
||||
help: this code is unreachable. Consider moving the reachable parts out
|
||||
--> tests/ui/never_loop.rs:440:9
|
||||
--> tests/ui/never_loop.rs:437:9
|
||||
|
|
||||
LL | return;
|
||||
| ^^^^^^^
|
||||
|
|
@ -213,7 +213,7 @@ LL + if let Some(v) = (0..10).next() {
|
|||
|
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:436:9
|
||||
--> tests/ui/never_loop.rs:433:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -222,7 +222,7 @@ LL | | }
|
|||
| |_________^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:443:5
|
||||
--> tests/ui/never_loop.rs:440:5
|
||||
|
|
||||
LL | / for v in 0..10 {
|
||||
LL | |
|
||||
|
|
@ -239,7 +239,7 @@ LL + if let Some(v) = (0..10).next() {
|
|||
|
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:445:9
|
||||
--> tests/ui/never_loop.rs:442:9
|
||||
|
|
||||
LL | / 'inner: loop {
|
||||
LL | |
|
||||
|
|
@ -248,7 +248,7 @@ LL | | }
|
|||
| |_________^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:471:5
|
||||
--> tests/ui/never_loop.rs:468:5
|
||||
|
|
||||
LL | / 'a: for _ in 0..1 {
|
||||
LL | |
|
||||
|
|
@ -264,7 +264,7 @@ LL ~
|
|||
|
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:477:5
|
||||
--> tests/ui/never_loop.rs:474:5
|
||||
|
|
||||
LL | / 'a: for i in 0..1 {
|
||||
LL | |
|
||||
|
|
@ -288,7 +288,7 @@ LL ~
|
|||
|
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:492:5
|
||||
--> tests/ui/never_loop.rs:489:5
|
||||
|
|
||||
LL | / for v in 0..10 {
|
||||
LL | |
|
||||
|
|
@ -311,7 +311,7 @@ LL ~
|
|||
|
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:503:5
|
||||
--> tests/ui/never_loop.rs:500:5
|
||||
|
|
||||
LL | / 'bar: for _ in 0..100 {
|
||||
LL | |
|
||||
|
|
@ -321,7 +321,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
|
||||
help: this code is unreachable. Consider moving the reachable parts out
|
||||
--> tests/ui/never_loop.rs:505:9
|
||||
--> tests/ui/never_loop.rs:502:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -336,7 +336,7 @@ LL + if let Some(_) = (0..100).next() {
|
|||
|
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:505:9
|
||||
--> tests/ui/never_loop.rs:502:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -346,7 +346,7 @@ LL | | }
|
|||
| |_________^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:512:5
|
||||
--> tests/ui/never_loop.rs:509:5
|
||||
|
|
||||
LL | / 'foo: for _ in 0..100 {
|
||||
LL | |
|
||||
|
|
@ -356,7 +356,7 @@ LL | | }
|
|||
| |_____^
|
||||
|
|
||||
help: this code is unreachable. Consider moving the reachable parts out
|
||||
--> tests/ui/never_loop.rs:514:9
|
||||
--> tests/ui/never_loop.rs:511:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -372,7 +372,7 @@ LL + if let Some(_) = (0..100).next() {
|
|||
|
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:514:9
|
||||
--> tests/ui/never_loop.rs:511:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -383,7 +383,7 @@ LL | | }
|
|||
| |_________^
|
||||
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:517:13
|
||||
--> tests/ui/never_loop.rs:514:13
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
@ -392,5 +392,17 @@ LL | | break 'foo;
|
|||
LL | | }
|
||||
| |_____________^
|
||||
|
||||
error: aborting due to 29 previous errors
|
||||
error: this loop never actually loops
|
||||
--> tests/ui/never_loop.rs:537:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | | unsafe {
|
||||
LL | | asm! {
|
||||
LL | | "/* {} */",
|
||||
... |
|
||||
LL | | return;
|
||||
LL | | }
|
||||
| |_____^
|
||||
|
||||
error: aborting due to 30 previous errors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue