From 134539060d16d4f86cc4edcb8a586c3be5f67275 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 14 Oct 2024 12:38:30 +0100 Subject: [PATCH 1/6] Rust: correct some 'spurious' annotations that are off by one line. --- rust/ql/test/query-tests/unusedentities/unreachable.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rust/ql/test/query-tests/unusedentities/unreachable.rs b/rust/ql/test/query-tests/unusedentities/unreachable.rs index 8a8fbcf70bdb..05163d4a082b 100644 --- a/rust/ql/test/query-tests/unusedentities/unreachable.rs +++ b/rust/ql/test/query-tests/unusedentities/unreachable.rs @@ -97,16 +97,16 @@ fn unreachable_panic() { if cond() { do_something(); - _ = false && panic!(); // does not panic due to short-circuiting - do_something(); // SPURIOUS: unreachable + _ = false && panic!(); // does not panic due to short-circuiting SPURIOUS: unreachable + do_something(); _ = false || panic!(); do_something(); // BAD: unreachable code [NOT DETECTED] } if cond() { do_something(); - _ = true || panic!(); // does not panic due to short-circuiting - do_something(); // SPURIOUS: unreachable + _ = true || panic!(); // does not panic due to short-circuiting SPURIOUS: unreachable + do_something(); _ = true && panic!(); do_something(); // BAD: unreachable code [NOT DETECTED] } From 528641c55a588fbe784ce287de0132f25dd55636 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 14 Oct 2024 12:22:44 +0100 Subject: [PATCH 2/6] Rust: Test spacing. --- .../unusedentities/UnreachableCode.expected | 18 +-- .../unusedentities/UnusedVariable.expected | 26 ++-- .../test/query-tests/unusedentities/main.rs | 122 ++++++++++++++++++ .../query-tests/unusedentities/unreachable.rs | 6 + 4 files changed, 150 insertions(+), 22 deletions(-) diff --git a/rust/ql/test/query-tests/unusedentities/UnreachableCode.expected b/rust/ql/test/query-tests/unusedentities/UnreachableCode.expected index 18831b723278..fa463c47fc35 100644 --- a/rust/ql/test/query-tests/unusedentities/UnreachableCode.expected +++ b/rust/ql/test/query-tests/unusedentities/UnreachableCode.expected @@ -3,12 +3,12 @@ | unreachable.rs:32:3:32:17 | ExprStmt | This code is never reached. | | unreachable.rs:39:3:39:17 | ExprStmt | This code is never reached. | | unreachable.rs:60:2:60:16 | ExprStmt | This code is never reached. | -| unreachable.rs:100:16:100:23 | ExprStmt | This code is never reached. | -| unreachable.rs:108:15:108:22 | ExprStmt | This code is never reached. | -| unreachable.rs:124:2:124:16 | ExprStmt | This code is never reached. | -| unreachable.rs:134:2:134:16 | ExprStmt | This code is never reached. | -| unreachable.rs:141:3:141:17 | ExprStmt | This code is never reached. | -| unreachable.rs:150:4:150:18 | ExprStmt | This code is never reached. | -| unreachable.rs:156:3:156:17 | ExprStmt | This code is never reached. | -| unreachable.rs:162:4:162:18 | ExprStmt | This code is never reached. | -| unreachable.rs:165:2:165:16 | ExprStmt | This code is never reached. | +| unreachable.rs:106:16:106:23 | ExprStmt | This code is never reached. | +| unreachable.rs:114:15:114:22 | ExprStmt | This code is never reached. | +| unreachable.rs:130:2:130:16 | ExprStmt | This code is never reached. | +| unreachable.rs:140:2:140:16 | ExprStmt | This code is never reached. | +| unreachable.rs:147:3:147:17 | ExprStmt | This code is never reached. | +| unreachable.rs:156:4:156:18 | ExprStmt | This code is never reached. | +| unreachable.rs:162:3:162:17 | ExprStmt | This code is never reached. | +| unreachable.rs:168:4:168:18 | ExprStmt | This code is never reached. | +| unreachable.rs:171:2:171:16 | ExprStmt | This code is never reached. | diff --git a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected index 8203501f3a23..ee87d297230b 100644 --- a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected +++ b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected @@ -1,16 +1,16 @@ | main.rs:25:9:25:9 | a | Variable is not used. | | main.rs:90:13:90:13 | d | Variable is not used. | | main.rs:141:5:141:5 | y | Variable is not used. | -| main.rs:164:9:164:9 | x | Variable is not used. | -| main.rs:202:17:202:17 | a | Variable is not used. | -| main.rs:210:20:210:22 | val | Variable is not used. | -| main.rs:223:14:223:16 | val | Variable is not used. | -| main.rs:240:22:240:24 | val | Variable is not used. | -| main.rs:248:24:248:26 | val | Variable is not used. | -| main.rs:257:13:257:15 | num | Variable is not used. | -| main.rs:272:12:272:12 | j | Variable is not used. | -| main.rs:294:25:294:25 | y | Variable is not used. | -| main.rs:298:28:298:28 | a | Variable is not used. | -| main.rs:302:9:302:9 | p | Variable is not used. | -| main.rs:309:13:309:13 | y | Variable is not used. | -| main.rs:317:21:317:21 | y | Variable is not used. | +| main.rs:168:9:168:9 | x | Variable is not used. | +| main.rs:250:17:250:17 | a | Variable is not used. | +| main.rs:258:20:258:22 | val | Variable is not used. | +| main.rs:271:14:271:16 | val | Variable is not used. | +| main.rs:288:22:288:24 | val | Variable is not used. | +| main.rs:296:24:296:26 | val | Variable is not used. | +| main.rs:305:13:305:15 | num | Variable is not used. | +| main.rs:320:12:320:12 | j | Variable is not used. | +| main.rs:342:25:342:25 | y | Variable is not used. | +| main.rs:346:28:346:28 | a | Variable is not used. | +| main.rs:350:9:350:9 | p | Variable is not used. | +| main.rs:378:13:378:13 | y | Variable is not used. | +| main.rs:386:21:386:21 | y | Variable is not used. | diff --git a/rust/ql/test/query-tests/unusedentities/main.rs b/rust/ql/test/query-tests/unusedentities/main.rs index 9b4fdb0cdd19..a3bfa2caa7b8 100644 --- a/rust/ql/test/query-tests/unusedentities/main.rs +++ b/rust/ql/test/query-tests/unusedentities/main.rs @@ -146,6 +146,10 @@ fn parameters( // --- loops --- + + + + fn loops() { let mut a: i64 = 10; let b: i64 = 20; @@ -171,10 +175,54 @@ fn loops() { println!("x is {}", x); } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + for x in 1..10 { assert!(x != 11); } + + + + + + + + + + } // --- lets --- @@ -302,6 +350,27 @@ fn if_lets_matches() { p => { // BAD: unused variable } } + + + + + + + + + + + + + + + + + + + + + } fn shadowing() -> i32 { @@ -322,7 +391,58 @@ fn shadowing() -> i32 { } } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + // --- main --- + fn main() { locals_1(); locals_2(); @@ -334,6 +454,8 @@ fn main() { if_lets_matches(); shadowing(); + + unreachable_if(); unreachable_panic(); unreachable_match(); diff --git a/rust/ql/test/query-tests/unusedentities/unreachable.rs b/rust/ql/test/query-tests/unusedentities/unreachable.rs index 05163d4a082b..8ac1907faaa3 100644 --- a/rust/ql/test/query-tests/unusedentities/unreachable.rs +++ b/rust/ql/test/query-tests/unusedentities/unreachable.rs @@ -79,6 +79,12 @@ fn unreachable_panic() { do_something(); // BAD: unreachable code [NOT DETECTED] } + + + + + + if cond() { let mut maybe; From e5885f65dba02e3fb76d86b4ae06e8fce9be9a87 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:10:23 +0100 Subject: [PATCH 3/6] Rust: Add more test cases for unused variables and unreachable code. --- .../unusedentities/UnusedVariable.expected | 6 + .../test/query-tests/unusedentities/main.rs | 186 +++++++++--------- .../query-tests/unusedentities/unreachable.rs | 10 +- 3 files changed, 104 insertions(+), 98 deletions(-) diff --git a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected index ee87d297230b..2c570b315070 100644 --- a/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected +++ b/rust/ql/test/query-tests/unusedentities/UnusedVariable.expected @@ -2,6 +2,8 @@ | main.rs:90:13:90:13 | d | Variable is not used. | | main.rs:141:5:141:5 | y | Variable is not used. | | main.rs:168:9:168:9 | x | Variable is not used. | +| main.rs:196:9:196:9 | x | Variable is not used. | +| main.rs:201:9:201:9 | x | Variable is not used. | | main.rs:250:17:250:17 | a | Variable is not used. | | main.rs:258:20:258:22 | val | Variable is not used. | | main.rs:271:14:271:16 | val | Variable is not used. | @@ -12,5 +14,9 @@ | main.rs:342:25:342:25 | y | Variable is not used. | | main.rs:346:28:346:28 | a | Variable is not used. | | main.rs:350:9:350:9 | p | Variable is not used. | +| main.rs:365:9:365:13 | right | Variable is not used. | +| main.rs:371:9:371:14 | right2 | Variable is not used. | | main.rs:378:13:378:13 | y | Variable is not used. | | main.rs:386:21:386:21 | y | Variable is not used. | +| main.rs:434:27:434:29 | val | Variable is not used. | +| main.rs:437:22:437:24 | acc | Variable is not used. | diff --git a/rust/ql/test/query-tests/unusedentities/main.rs b/rust/ql/test/query-tests/unusedentities/main.rs index a3bfa2caa7b8..2edcc4b87160 100644 --- a/rust/ql/test/query-tests/unusedentities/main.rs +++ b/rust/ql/test/query-tests/unusedentities/main.rs @@ -146,9 +146,9 @@ fn parameters( // --- loops --- - - - +fn id(v: i32) -> i32 { + return v; +} fn loops() { let mut a: i64 = 10; @@ -175,53 +175,53 @@ fn loops() { println!("x is {}", x); } + for x + in 1..10 { + println!("x is {:?}", x); + } + for x + in 1..10 { + println!("x + 1 is {}", x + 1); + } + for x + in 1..10 { + for y + in 1..x { + println!("y is {}", y); + } + } + for x // SPURIOUS: unused variable + in 1..10 { + println!("x is {x}"); + } + for x // SPURIOUS: unused variable + in 1..10 { + _ = format!("x is {x}"); + } - - - - - - - - - - - - - - - - - - - - - - - - - - - - + for x + in 1..10 { + println!("x is {val}", val = x); + } for x in 1..10 { assert!(x != 11); } + for x + in 1..10 { + assert_eq!(x, 1); + } - - - - - - - + for x + in 1..10 { + assert_eq!(id(x), id(1)); + } } @@ -351,26 +351,26 @@ fn if_lets_matches() { } } + let duration1 = std::time::Duration::new(10, 0); // ten seconds + assert_eq!(duration1.as_secs(), 10); + let duration2:Result = + Ok(std::time::Duration::new(10, 0)); + match (duration2) { + Ok(n) => { println!("duration was {} seconds", n.as_secs()); } + Err(_) => { println!("failed"); } + } + let(left, + right) = // BAD: unused value [NOT DETECTED] SPURIOUS: unused variable + (1, 2); + _ = left; - - - - - - - - - - - - - - - - - + let pair = (1, 2); + let(left2, + right2) = // BAD: unused value [NOT DETECTED] SPURIOUS: unused variable + pair; + _ = left2; } fn shadowing() -> i32 { @@ -391,55 +391,55 @@ fn shadowing() -> i32 { } } +// --- function pointers --- +type FuncPtr = fn(i32) -> i32; +fn increment(x: i32) -> i32 { + return x + 1; +} +fn func_ptrs() { + let MyFunc: FuncPtr = increment; + for x + in 1..10 { + _ = x + 1; + } + for x + in 1..10 { + _ = increment(x); + } + for x + in 1..10 { + _ = MyFunc(x); + } +} +// --- folds and closures --- +fn folds_and_closures() { + let a1 = 1..10; + _ = a1.sum::(); + let a2 = 1..10; + _ = a2.fold(0, | acc: i32, val: i32 | -> i32 { acc + val } ); + let a3 = 1..10; + _ = a3.fold(0, | acc, val | acc + val); + let a4 = 1..10; + _ = a4.fold(0, | acc, val | acc); // BAD: unused variable + let a5 = 1..10; + _ = a5.fold(0, | acc, val | val); // BAD: unused variable - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + let i6 = 1; + let a6 = 1..10; + _ = a6.fold(0, | acc, val | acc + val + i6); +} // --- main --- @@ -453,8 +453,8 @@ fn main() { loops(); if_lets_matches(); shadowing(); - - + func_ptrs(); + folds_and_closures(); unreachable_if(); unreachable_panic(); diff --git a/rust/ql/test/query-tests/unusedentities/unreachable.rs b/rust/ql/test/query-tests/unusedentities/unreachable.rs index 8ac1907faaa3..328c6edf0ea0 100644 --- a/rust/ql/test/query-tests/unusedentities/unreachable.rs +++ b/rust/ql/test/query-tests/unusedentities/unreachable.rs @@ -79,11 +79,11 @@ fn unreachable_panic() { do_something(); // BAD: unreachable code [NOT DETECTED] } - - - - - + if cond() { + do_something(); + unreachable!(); + do_something(); // BAD: unreachable code [NOT DETECTED] + } if cond() { let mut maybe; From 57875554f4c90d4ea37c9b79ad204f190fd2d808 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 14 Oct 2024 17:06:55 +0100 Subject: [PATCH 4/6] Rust: Accept consistency failures in the new test cases. --- .../CONSISTENCY/CfgConsistency.expected | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 rust/ql/test/query-tests/unusedentities/CONSISTENCY/CfgConsistency.expected diff --git a/rust/ql/test/query-tests/unusedentities/CONSISTENCY/CfgConsistency.expected b/rust/ql/test/query-tests/unusedentities/CONSISTENCY/CfgConsistency.expected new file mode 100644 index 000000000000..bdd995b19f3e --- /dev/null +++ b/rust/ql/test/query-tests/unusedentities/CONSISTENCY/CfgConsistency.expected @@ -0,0 +1,11 @@ +multipleSuccessors +| main.rs:428:17:428:17 | 0 | successor | main.rs:428:9:428:10 | a2 | +| main.rs:428:17:428:17 | 0 | successor | main.rs:428:20:428:62 | ClosureExpr | +| main.rs:431:17:431:17 | 0 | successor | main.rs:431:9:431:10 | a3 | +| main.rs:431:17:431:17 | 0 | successor | main.rs:431:20:431:41 | ClosureExpr | +| main.rs:434:17:434:17 | 0 | successor | main.rs:434:9:434:10 | a4 | +| main.rs:434:17:434:17 | 0 | successor | main.rs:434:20:434:35 | ClosureExpr | +| main.rs:437:17:437:17 | 0 | successor | main.rs:437:9:437:10 | a5 | +| main.rs:437:17:437:17 | 0 | successor | main.rs:437:20:437:35 | ClosureExpr | +| main.rs:441:17:441:17 | 0 | successor | main.rs:441:9:441:10 | a6 | +| main.rs:441:17:441:17 | 0 | successor | main.rs:441:20:441:46 | ClosureExpr | From 8169ccd21ede3fd97e8677b71ab0879f89e4628b Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 15 Oct 2024 09:36:09 +0100 Subject: [PATCH 5/6] Apply suggestions from code review Co-authored-by: Simon Friis Vindum --- rust/ql/test/query-tests/unusedentities/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/ql/test/query-tests/unusedentities/main.rs b/rust/ql/test/query-tests/unusedentities/main.rs index 2edcc4b87160..21403ac3ddf1 100644 --- a/rust/ql/test/query-tests/unusedentities/main.rs +++ b/rust/ql/test/query-tests/unusedentities/main.rs @@ -356,7 +356,7 @@ fn if_lets_matches() { let duration2:Result = Ok(std::time::Duration::new(10, 0)); - match (duration2) { + match duration2 { Ok(n) => { println!("duration was {} seconds", n.as_secs()); } Err(_) => { println!("failed"); } } @@ -400,7 +400,7 @@ fn increment(x: i32) -> i32 { } fn func_ptrs() { - let MyFunc: FuncPtr = increment; + let my_func: FuncPtr = increment; for x in 1..10 { @@ -414,7 +414,7 @@ fn func_ptrs() { for x in 1..10 { - _ = MyFunc(x); + _ = my_func(x); } } From 5e33d9a14586ad05b4262fadab71494abe857423 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 15 Oct 2024 09:37:43 +0100 Subject: [PATCH 6/6] Rust: Further changes from code review. --- rust/ql/test/query-tests/unusedentities/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/ql/test/query-tests/unusedentities/main.rs b/rust/ql/test/query-tests/unusedentities/main.rs index 21403ac3ddf1..3b81b0db54a9 100644 --- a/rust/ql/test/query-tests/unusedentities/main.rs +++ b/rust/ql/test/query-tests/unusedentities/main.rs @@ -361,13 +361,13 @@ fn if_lets_matches() { Err(_) => { println!("failed"); } } - let(left, + let (left, right) = // BAD: unused value [NOT DETECTED] SPURIOUS: unused variable (1, 2); _ = left; let pair = (1, 2); - let(left2, + let (left2, right2) = // BAD: unused value [NOT DETECTED] SPURIOUS: unused variable pair; _ = left2;