Rust: Post-processing query for inline test expectations

This commit is contained in:
Tom Hvitved
2024-10-07 13:12:19 +02:00
parent 1259b7e8e7
commit dd520fea47
10 changed files with 342 additions and 337 deletions

View File

@@ -1,16 +1,16 @@
| unreachable.rs:13:3:13:17 | ExprStmt | This code is never reached. |
| unreachable.rs:21:3:21:17 | ExprStmt | This code is never reached. |
| unreachable.rs:33:3:33:17 | ExprStmt | This code is never reached. |
| unreachable.rs:40:3:40:17 | ExprStmt | This code is never reached. |
| unreachable.rs:61:2:61:16 | ExprStmt | This code is never reached. |
| unreachable.rs:107:16:107:23 | ExprStmt | This code is never reached. |
| unreachable.rs:115:15:115:22 | ExprStmt | This code is never reached. |
| unreachable.rs:141:2:141:16 | ExprStmt | This code is never reached. |
| unreachable.rs:148:3:148:17 | ExprStmt | This code is never reached. |
| unreachable.rs:157:4:157:18 | ExprStmt | This code is never reached. |
| unreachable.rs:163:3:163:17 | ExprStmt | This code is never reached. |
| unreachable.rs:169:4:169:18 | ExprStmt | This code is never reached. |
| unreachable.rs:177:4:177:18 | ExprStmt | This code is never reached. |
| unreachable.rs:180:2:180:16 | ExprStmt | This code is never reached. |
| unreachable.rs:203:3:203:17 | ExprStmt | This code is never reached. |
| unreachable.rs:218:3:218:17 | ExprStmt | This code is never reached. |
| unreachable.rs:11:9:11:23 | ExprStmt | This code is never reached. |
| unreachable.rs:19:9:19:23 | ExprStmt | This code is never reached. |
| unreachable.rs:31:9:31:23 | ExprStmt | This code is never reached. |
| unreachable.rs:38:9:38:23 | ExprStmt | This code is never reached. |
| unreachable.rs:59:5:59:19 | ExprStmt | This code is never reached. |
| unreachable.rs:106:13:106:20 | ExprStmt | This code is never reached. |
| unreachable.rs:115:13:115:20 | ExprStmt | This code is never reached. |
| unreachable.rs:141:5:141:19 | ExprStmt | This code is never reached. |
| unreachable.rs:148:9:148:23 | ExprStmt | This code is never reached. |
| unreachable.rs:157:13:157:27 | ExprStmt | This code is never reached. |
| unreachable.rs:163:9:163:23 | ExprStmt | This code is never reached. |
| unreachable.rs:169:13:169:27 | ExprStmt | This code is never reached. |
| unreachable.rs:177:13:177:27 | ExprStmt | This code is never reached. |
| unreachable.rs:180:5:180:19 | ExprStmt | This code is never reached. |
| unreachable.rs:204:9:204:23 | ExprStmt | This code is never reached. |
| unreachable.rs:220:9:220:23 | ExprStmt | This code is never reached. |

View File

@@ -1 +1,2 @@
queries/unusedentities/UnreachableCode.ql
query: queries/unusedentities/UnreachableCode.ql
postprocess: utils/InlineExpectationsTestQuery.ql

View File

@@ -10,15 +10,15 @@
| main.rs:65:5:65:5 | g | Variable is assigned a value that is never used. |
| main.rs:87:9:87:9 | a | Variable is assigned a value that is never used. |
| main.rs:108:9:108:10 | is | Variable is assigned a value that is never used. |
| main.rs:133:13:133:17 | total | Variable is assigned a value that is never used. |
| main.rs:203:13:203:31 | res | Variable is assigned a value that is never used. |
| main.rs:218:9:218:24 | kind | Variable is assigned a value that is never used. |
| main.rs:223:9:223:32 | kind | Variable is assigned a value that is never used. |
| main.rs:280:13:280:17 | total | Variable is assigned a value that is never used. |
| main.rs:348:5:348:39 | kind | Variable is assigned a value that is never used. |
| main.rs:370:9:370:9 | x | Variable is assigned a value that is never used. |
| main.rs:378:17:378:17 | x | Variable is assigned a value that is never used. |
| main.rs:131:13:131:17 | total | Variable is assigned a value that is never used. |
| main.rs:194:13:194:31 | res | Variable is assigned a value that is never used. |
| main.rs:206:9:206:24 | kind | Variable is assigned a value that is never used. |
| main.rs:210:9:210:32 | kind | Variable is assigned a value that is never used. |
| main.rs:266:13:266:17 | total | Variable is assigned a value that is never used. |
| main.rs:334:5:334:39 | kind | Variable is assigned a value that is never used. |
| main.rs:359:9:359:9 | x | Variable is assigned a value that is never used. |
| main.rs:367:17:367:17 | x | Variable is assigned a value that is never used. |
| more.rs:24:9:24:11 | val | Variable is assigned a value that is never used. |
| more.rs:46:9:46:14 | a_ptr4 | Variable is assigned a value that is never used. |
| more.rs:61:9:61:13 | d_ptr | Variable is assigned a value that is never used. |
| more.rs:67:9:67:17 | f_ptr | Variable is assigned a value that is never used. |
| more.rs:44:9:44:14 | a_ptr4 | Variable is assigned a value that is never used. |
| more.rs:59:9:59:13 | d_ptr | Variable is assigned a value that is never used. |
| more.rs:65:9:65:17 | f_ptr | Variable is assigned a value that is never used. |

View File

@@ -1 +1,2 @@
queries/unusedentities/UnusedValue.ql
query: queries/unusedentities/UnusedValue.ql
postprocess: utils/InlineExpectationsTestQuery.ql

View File

@@ -1,21 +1,21 @@
| 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: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:272:14:272:16 | val | Variable is not used. |
| main.rs:287:22:287:24 | val | Variable is not used. |
| main.rs:294:24:294:26 | val | Variable is not used. |
| main.rs:302:13:302:15 | num | Variable is not used. |
| main.rs:317:12:317:12 | j | Variable is not used. |
| main.rs:337:25:337:25 | y | Variable is not used. |
| main.rs:340:28:340:28 | a | Variable is not used. |
| main.rs:343:9:343:9 | p | Variable is not used. |
| main.rs:358:9:358:13 | right | Variable is not used. |
| main.rs:364:9:364:14 | right2 | Variable is not used. |
| main.rs:371:13:371:13 | y | Variable is not used. |
| main.rs:379:21:379:21 | y | Variable is not used. |
| main.rs:427:27:427:29 | val | Variable is not used. |
| main.rs:430:22:430:24 | acc | Variable is not used. |
| main.rs:455:9:455:14 | unused | Variable is not used. |
| main.rs:139:5:139:5 | y | Variable is not used. |
| main.rs:166:9:166:9 | x | Variable is not used. |
| main.rs:236:17:236:17 | a | Variable is not used. |
| main.rs:244:20:244:22 | val | Variable is not used. |
| main.rs:258:14:258:16 | val | Variable is not used. |
| main.rs:273:22:273:24 | val | Variable is not used. |
| main.rs:280:24:280:26 | val | Variable is not used. |
| main.rs:288:13:288:15 | num | Variable is not used. |
| main.rs:303:12:303:12 | j | Variable is not used. |
| main.rs:323:25:323:25 | y | Variable is not used. |
| main.rs:326:28:326:28 | a | Variable is not used. |
| main.rs:329:9:329:9 | p | Variable is not used. |
| main.rs:347:9:347:13 | right | Variable is not used. |
| main.rs:353:9:353:14 | right2 | Variable is not used. |
| main.rs:360:13:360:13 | y | Variable is not used. |
| main.rs:368:21:368:21 | y | Variable is not used. |
| main.rs:413:26:413:28 | val | Variable is not used. |
| main.rs:416:21:416:23 | acc | Variable is not used. |
| main.rs:437:9:437:14 | unused | Variable is not used. |

View File

@@ -1 +1,2 @@
queries/unusedentities/UnusedVariable.ql
query: queries/unusedentities/UnusedVariable.ql
postprocess: utils/InlineExpectationsTestQuery.ql

View File

@@ -3,10 +3,10 @@
// --- locals ---
fn locals_1() {
let a = 1; // BAD: unused value
let a = 1; // $ Alert[rust/unused-value]
let b = 1;
let c = 1;
let d = String::from("a"); // BAD: unused value
let d = String::from("a"); // $ Alert[rust/unused-value]
let e = String::from("b");
let f = 1;
let _ = 1; // (deliberately unused)
@@ -22,7 +22,7 @@ fn locals_1() {
}
fn locals_2() {
let a: i32; // BAD: unused variable
let a: i32; // $ Alert[rust/unused-variable]
let b: i32;
let mut c: i32;
let mut d: i32;
@@ -32,22 +32,22 @@ fn locals_2() {
let h: i32;
let i: i32;
b = 1; // BAD: unused value
b = 1; // $ Alert[rust/unused-value]
c = 1; // BAD: unused value
c = 1; // $ Alert[rust/unused-value]
c = 2;
println!("use {}", c);
c = 3; // BAD: unused value
c = 3; // $ Alert[rust/unused-value]
d = 1;
if cond() {
d = 2; // BAD: unused value
d = 2; // $ Alert[rust/unused-value]
d = 3;
} else {
}
println!("use {}", d);
e = 1; // BAD: unused value
e = 1; // $ Alert[rust/unused-value]
if cond() {
e = 2;
} else {
@@ -58,11 +58,11 @@ fn locals_2() {
f = 1;
f += 1;
println!("use {}", f);
f += 1; // BAD: unused value
f += 1; // $ Alert[rust/unused-value]
f = 1;
f += 1; // BAD: unused value
f += 1; // $ Alert[rust/unused-value]
g = if cond() { 1 } else { 2 }; // BAD: unused value
g = if cond() { 1 } else { 2 }; // $ Alert[rust/unused-value]
h = if cond() { 3 } else { 4 };
i = if cond() { h } else { 5 };
println!("use {}", i);
@@ -84,10 +84,10 @@ impl MyStruct {
}
fn structs() {
let a = MyStruct { val: 1 }; // BAD: unused value
let a = MyStruct { val: 1 }; // $ Alert[rust/unused-value]
let b = MyStruct { val: 2 };
let c = MyStruct { val: 3 };
let mut d: MyStruct; // BAD: unused variable
let mut d: MyStruct; // $ Alert[rust/unused-variable]
let mut e: MyStruct;
let mut f: MyStruct;
@@ -98,22 +98,20 @@ fn structs() {
e.val = 5;
println!("lets use {}", e.my_get());
f = MyStruct { val: 6 }; // BAD: unused value [NOT DETECTED]
f.val = 7; // BAD: unused value [NOT DETECTED]
f = MyStruct { val: 6 }; // $ MISSING: Alert[rust/unused-value]
f.val = 7; // $ MISSING: Alert[rust/unused-value]
}
// --- arrays ---
fn arrays() {
let is = [1, 2, 3]; // BAD: unused value
let is = [1, 2, 3]; // $ Alert[rust/unused-value]
let js = [1, 2, 3];
let ks = [1, 2, 3];
println!("lets use {:?}", js);
for k
in ks
{
for k in ks {
println!("lets use {}", k); // [unreachable FALSE POSITIVE]
}
}
@@ -121,16 +119,16 @@ fn arrays() {
// --- constants and statics ---
const CON1: i32 = 1;
const CON2: i32 = 2; // BAD: unused value [NOT DETECTED]
const CON2: i32 = 2; // $ MISSING: Alert[rust/unused-value]
static mut STAT1: i32 = 1;
static mut STAT2: i32 = 2; // BAD: unused value [NOT DETECTED]
static mut STAT2: i32 = 2; // $ MISSING: Alert[rust/unused-value]
fn statics() {
static mut STAT3: i32 = 0;
static mut STAT4: i32 = 0; // BAD: unused value [NOT DETECTED]
static mut STAT4: i32 = 0; // $ MISSING: Alert[rust/unused-value]
unsafe {
let total = CON1 + STAT1 + STAT3; // BAD: unused value
let total = CON1 + STAT1 + STAT3; // $ Alert[rust/unused-value]
}
}
@@ -138,7 +136,7 @@ fn statics() {
fn parameters(
x: i32,
y: i32, // BAD: unused variable
y: i32, // $ Alert[rust/unused-variable]
_z: i32, // (`_` is asking the compiler, and by extension us, to not warn that this is unused)
) -> i32 {
return x;
@@ -165,64 +163,52 @@ fn loops() {
e += x;
}
for x in 1..10 { // BAD: unused variable
for x in 1..10 { // $ Alert[rust/unused-variable]
}
for _ in 1..10 {}
for x
in 1..10 {
for x in 1..10 {
println!("x is {}", x);
}
for x
in 1..10 {
for x in 1..10 {
println!("x is {:?}", x);
}
for x
in 1..10 {
for x in 1..10 {
println!("x + 1 is {}", x + 1);
}
for x
in 1..10 {
for y
in 1..x {
for x in 1..10 {
for y in 1..x {
println!("y is {}", y);
}
}
for x
in 1..10 {
for x in 1..10 {
println!("x is {x}");
}
for x
in 1..10 {
_ = format!("x is {x}"); // SPURIOUS: unused value `res`
for x in 1..10 {
_ = format!("x is {x}"); // $ SPURIOUS: Alert[rust/unused-value]
}
for x
in 1..10 {
for x in 1..10 {
println!("x is {val}", val = x);
}
for x
in 1..10 {
for x in 1..10 {
assert!(x != 11);
}
for x
in 1..10 {
assert_eq!(x, 1); // SPURIOUS: unused value `kind`
for x in 1..10 {
assert_eq!(x, 1); // $ SPURIOUS: Alert[rust/unused-value]
}
for x
in 1..10 {
assert_eq!(id(x), id(1)); // SPURIOUS: unused value `kind`
for x in 1..10 {
assert_eq!(id(x), id(1)); // $ SPURIOUS: Alert[rust/unused-value]
}
}
// --- lets ---
@@ -237,7 +223,7 @@ enum YesOrNo {
No,
}
use YesOrNo::{Yes, No}; // allows `Yes`, `No` to be accessed without qualifiers.
use YesOrNo::{No, Yes}; // allows `Yes`, `No` to be accessed without qualifiers.
struct MyPoint {
x: i64,
@@ -247,7 +233,7 @@ struct MyPoint {
fn if_lets_matches() {
let mut total: i64 = 0;
if let Some(a) = Some(10) { // BAD: unused variable
if let Some(a) = Some(10) { // $ Alert[rust/unused-variable]
}
if let Some(b) = Some(20) {
@@ -255,7 +241,7 @@ fn if_lets_matches() {
}
let mut next = Some(30);
while let Some(val) = // BAD: unused variable
while let Some(val) = // $ Alert[rust/unused-variable]
next
{
next = None;
@@ -269,7 +255,7 @@ fn if_lets_matches() {
let c = Some(60);
match c {
Some(val) => { // BAD: unused variable
Some(val) => { // $ Alert[rust/unused-variable]
}
None => {}
}
@@ -277,21 +263,21 @@ fn if_lets_matches() {
let d = Some(70);
match d {
Some(val) => {
total += val; // BAD: unused value
total += val; // $ Alert[rust/unused-value]
}
None => {}
}
let e = Option::Some(80);
match e {
Option::Some(val) => { // BAD: unused variable
Option::Some(val) => { // $ Alert[rust/unused-variable]
}
Option::None => {}
}
let f = MyOption::Some(90);
match f {
MyOption::Some(val) => { // BAD: unused variable
MyOption::Some(val) => { // $ Alert[rust/unused-variable]
}
MyOption::None => {}
}
@@ -299,7 +285,7 @@ fn if_lets_matches() {
let g: Result<i64, i64> = Ok(100);
match g {
Ok(_) => {}
Err(num) => {} // BAD: unused variable
Err(num) => {} // $ Alert[rust/unused-variable]
}
let h = YesOrNo::Yes;
@@ -314,7 +300,7 @@ fn if_lets_matches() {
No => {}
}
if let j = Yes { // BAD: unused variable
if let j = Yes { // $ Alert[rust/unused-variable]
}
if let k = Yes {
@@ -334,49 +320,52 @@ fn if_lets_matches() {
let p1 = MyPoint { x: 1, y: 2 };
match p1 {
MyPoint { x: 0, y: 0 } => {}
MyPoint { x: 1, y } => { // BAD: unused variable
MyPoint { x: 1, y } => { // $ Alert[rust/unused-variable]
}
MyPoint { x: 2, y: _ } => {}
MyPoint { x: 3, y: a } => { // BAD: unused variable
MyPoint { x: 3, y: a } => { // $ Alert[rust/unused-variable]
}
MyPoint { x: 4, .. } => {}
p => { // BAD: unused variable
p => { // $ Alert[rust/unused-variable]
}
}
let duration1 = std::time::Duration::new(10, 0); // ten seconds
assert_eq!(duration1.as_secs(), 10); // SPURIOUS: unused value `kind`
assert_eq!(duration1.as_secs(), 10); // $ SPURIOUS: Alert[rust/unused-value]
let duration2:Result<std::time::Duration, String> =
Ok(std::time::Duration::new(10, 0));
let duration2: Result<std::time::Duration, String> = Ok(std::time::Duration::new(10, 0));
match duration2 {
Ok(n) => { println!("duration was {} seconds", n.as_secs()); }
Err(_) => { println!("failed"); }
Ok(n) => {
println!("duration was {} seconds", n.as_secs());
}
Err(_) => {
println!("failed");
}
}
let (left,
right) = // BAD: unused value [NOT DETECTED] SPURIOUS: unused variable
right) = // $ MISSING: Alert[rust/unused-value] $ SPURIOUS: Alert[rust/unused-variable]
(1, 2);
_ = left;
let pair = (1, 2);
let (left2,
right2) = // BAD: unused value [NOT DETECTED] SPURIOUS: unused variable
right2) = // $ MISSING: Alert[rust/unused-value] $ SPURIOUS: Alert[rust/unused-variable]
pair;
_ = left2;
}
fn shadowing() -> i32 {
let x = 1; // BAD: unused value
let mut y: i32; // BAD: unused variable
let x = 1; // $ Alert[rust/unused-value]
let mut y: i32; // $ Alert[rust/unused-variable]
{
let x = 2;
let mut y: i32;
{
let x = 3; // BAD: unused value
let mut y: i32; // BAD: unused variable
let x = 3; // $ Alert[rust/unused-value]
let mut y: i32; // $ Alert[rust/unused-variable]
}
y = x;
@@ -395,18 +384,15 @@ fn increment(x: i32) -> i32 {
fn func_ptrs() {
let my_func: FuncPtr = increment;
for x
in 1..10 {
for x in 1..10 {
_ = x + 1;
}
for x
in 1..10 {
for x in 1..10 {
_ = increment(x);
}
for x
in 1..10 {
for x in 1..10 {
_ = my_func(x);
}
}
@@ -418,30 +404,26 @@ fn folds_and_closures() {
_ = a1.sum::<i32>();
let a2 = 1..10;
_ = a2.fold(0, | acc: i32, val: i32 | -> i32 { acc + val } );
_ = a2.fold(0, |acc: i32, val: i32| -> i32 { acc + val });
let a3 = 1..10;
_ = a3.fold(0, | acc, val | acc + val);
_ = a3.fold(0, |acc, val| acc + val);
let a4 = 1..10;
_ = a4.fold(0, | acc, val | acc); // BAD: unused variable
_ = a4.fold(0, |acc, val| acc); // $ Alert[rust/unused-variable]
let a5 = 1..10;
_ = a5.fold(0, | acc, val | val); // BAD: unused variable
_ = a5.fold(0, |acc, val| val); // $ Alert[rust/unused-variable]
let i6 = 1;
let a6 = 1..10;
_ = a6.fold(0, | acc, val | acc + val + i6);
_ = a6.fold(0, |acc, val| acc + val + i6);
}
// --- traits ---
trait Incrementable {
fn increment(
&mut self,
times: i32,
unused: &mut i32
);
fn increment(&mut self, times: i32, unused: &mut i32);
}
struct MyValue {
@@ -452,7 +434,7 @@ impl Incrementable for MyValue {
fn increment(
&mut self,
times: i32,
unused: i32 // BAD: unused variable
unused: i32, // $ Alert[rust/unused-variable]
) {
self.value += times;
}
@@ -490,5 +472,4 @@ fn main() {
unreachable_let_2();
unreachable_if_2();
unreachable_if_3();
}

View File

@@ -9,7 +9,7 @@ trait MyGettable<T> {
}
struct MyContainer<T> {
val: T
val: T,
}
impl<T> MySettable<T> for MyContainer<T> {
@@ -21,19 +21,17 @@ impl<T> MySettable<T> for MyContainer<T> {
impl<T> MyGettable<T> for MyContainer<T> {
fn get(
&self,
val: T // BAD: unused variable [NOT DETECTED] SPURIOUS: unused value
val: T, // $ SPURIOUS: Alert[rust/unused-value] $ MISSING: Alert[rust/unused-variable]
) -> &T {
return &(self.val);
}
}
fn generics() {
let mut a = MyContainer { val: 1 }; // BAD: unused value [NOT DETECTED]
let mut a = MyContainer { val: 1 }; // $ MISSING: Alert[rust/unused-value]
let b = MyContainer { val: 2 };
a.set(
*b.get(3)
);
a.set(*b.get(3));
}
// --- pointers ---
@@ -42,13 +40,13 @@ fn pointers() {
let a = 1;
let a_ptr1 = &a;
let a_ptr2 = &a;
let a_ptr3 = &a; // BAD: unused value [NOT DETECTED]
let a_ptr4 = &a; // BAD: unused value
let a_ptr3 = &a; // $ MISSING: Alert[rust/unused-value]
let a_ptr4 = &a; // $ Alert[rust/unused-value]
println!("{}", *a_ptr1);
println!("{}", a_ptr2);
println!("{}", &a_ptr3);
let b = 2; // BAD: unused value [NOT DETECTED]
let b = 2; // $ MISSING: Alert[rust/unused-value]
let b_ptr = &b;
println!("{}", b_ptr);
@@ -58,26 +56,26 @@ fn pointers() {
println!("{}", **c_ptr_ptr);
let d = 4;
let d_ptr = &d; // BAD: unused value
let d_ptr = &d; // $ Alert[rust/unused-value]
let d_ptr_ptr = &&d;
println!("{}", **d_ptr_ptr);
let e = 5; // BAD: unused value [NOT DETECTED]
let e = 5; // $ MISSING: Alert[rust/unused-value]
let f = 6;
let mut f_ptr = &e; // BAD: unused value
let mut f_ptr = &e; // $ Alert[rust/unused-value]
f_ptr = &f;
println!("{}", *f_ptr);
let mut g = 7; // BAD: unused value [NOT DETECTED]
let mut g = 7; // $ MISSING: Alert[rust/unused-value]
let g_ptr = &mut g;
*g_ptr = 77; // BAD: unused value [NOT DETECTED]
*g_ptr = 77; // $ MISSING: Alert[rust/unused-value]
let mut h = 8; // BAD: unused value [NOT DETECTED]
let mut h = 8; // $ MISSING: Alert[rust/unused-value]
let h_ptr = &mut h;
*h_ptr = 88;
println!("{}", h);
let mut i = 9; // BAD: unused value [NOT DETECTED]
let mut i = 9; // $ MISSING: Alert[rust/unused-value]
let i_ptr = &mut i;
*i_ptr = 99;
let i_ptr2 = &mut i;

View File

@@ -1,243 +1,245 @@
//fn cond() -> bool;
//fn get_a_number() -> i32;
//fn maybe_get_a_number() -> Option<i32>;
// --- unreachable code --
fn do_something() {
}
fn do_something() {}
fn unreachable_if_1() {
if false {
do_something(); // BAD: unreachable code
} else {
do_something();
}
if false {
do_something(); // $ Alert[rust/dead-code]
} else {
do_something();
}
if true {
do_something();
} else {
do_something(); // BAD: unreachable code
}
if true {
do_something();
} else {
do_something(); // $ Alert[rust/dead-code]
}
let v = get_a_number();
if v == 1 {
if v != 1 {
do_something(); // BAD: unreachable code [NOT DETECTED]
}
}
let v = get_a_number();
if v == 1 {
if v != 1 {
do_something(); // $ MISSING: Alert[rust/dead-code]
}
}
if cond() {
return;
do_something(); // BAD: unreachable code
}
if cond() {
return;
do_something(); // $ Alert[rust/dead-code]
}
if cond() {
do_something();
} else {
return;
do_something(); // BAD: unreachable code
}
do_something();
if cond() {
do_something();
} else {
return;
do_something(); // $ Alert[rust/dead-code]
}
do_something();
if cond() {
let x = cond();
if cond() {
let x = cond();
if (x) {
do_something();
if (!x) {
do_something(); // BAD: unreachable code [NOT DETECTED]
}
do_something();
}
}
if (x) {
do_something();
if (!x) {
do_something(); // $ MISSING: Alert[rust/dead-code]
}
do_something();
}
}
if cond() {
return;
} else {
return;
}
do_something(); // BAD: unreachable code
if cond() {
return;
} else {
return;
}
do_something(); // $ Alert[rust/dead-code]
}
fn unreachable_panic() {
if cond() {
do_something();
panic!("Oh no!!!");
do_something(); // BAD: unreachable code [NOT DETECTED]
}
if cond() {
do_something();
panic!("Oh no!!!");
do_something(); // $ MISSING: Alert[rust/dead-code]
}
if cond() {
do_something();
unimplemented!();
do_something(); // BAD: unreachable code [NOT DETECTED]
}
if cond() {
do_something();
unimplemented!();
do_something(); // $ MISSING: Alert[rust/dead-code]
}
if cond() {
do_something();
todo!();
do_something(); // BAD: unreachable code [NOT DETECTED]
}
if cond() {
do_something();
todo!();
do_something(); // $ MISSING: Alert[rust/dead-code]
}
if cond() {
do_something();
unreachable!();
do_something(); // BAD: unreachable code [NOT DETECTED]
}
if cond() {
do_something();
unreachable!();
do_something(); // $ MISSING: Alert[rust/dead-code]
}
if cond() {
let mut maybe;
if cond() {
let mut maybe;
maybe = Some("Thing");
_ = maybe.unwrap(); // (safe)
do_something();
maybe = Some("Thing");
_ = maybe.unwrap(); // (safe)
do_something();
maybe = if cond() { Some("Other") } else { None };
_ = maybe.unwrap(); // (might panic)
do_something();
maybe = if cond() { Some("Other") } else { None };
_ = maybe.unwrap(); // (might panic)
do_something();
maybe = None;
_ = maybe.unwrap(); // (always panics)
do_something(); // BAD: unreachable code [NOT DETECTED]
}
maybe = None;
_ = maybe.unwrap(); // (always panics)
do_something(); // $ MISSING: Alert[rust/dead-code]
}
if cond() {
do_something();
_ = 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();
_ = false && // .
panic!(); // $ Alert[rust/dead-code]
do_something();
_ = false || panic!();
do_something(); // $ MISSING: Alert[rust/dead-code]
}
if cond() {
do_something();
_ = true || panic!(); // does not panic due to short-circuiting SPURIOUS: unreachable
do_something();
_ = true && panic!();
do_something(); // BAD: unreachable code [NOT DETECTED]
}
if cond() {
do_something();
_ = true || // .
panic!(); // $ Alert[rust/dead-code]
do_something();
_ = true && panic!();
do_something(); // $ MISSING: Alert[rust/dead-code]
}
}
fn unreachable_match() {
match get_a_number() {
1=>{
return;
}
_=>{
do_something();
}
}
do_something();
match get_a_number() {
1 => {
return;
}
_ => {
do_something();
}
}
do_something();
match get_a_number() {
1=>{
return;
}
_=>{
return;
}
}
do_something(); // BAD: unreachable code
match get_a_number() {
1 => {
return;
}
_ => {
return;
}
}
do_something(); // $ Alert[rust/dead-code]
}
fn unreachable_loop() {
loop {
do_something();
break;
do_something(); // BAD: unreachable code
}
loop {
do_something();
break;
do_something(); // $ Alert[rust/dead-code]
}
if cond() {
while cond() {
do_something();
}
if cond() {
while cond() {
do_something();
}
while false {
do_something(); // BAD: unreachable code
}
while false {
do_something(); // $ Alert[rust/dead-code]
}
while true {
do_something();
}
do_something(); // BAD: unreachable code
}
while true {
do_something();
}
do_something(); // $ Alert[rust/dead-code]
}
for _ in 1..10 {
if cond() {
continue;
do_something(); // BAD: unreachable code
}
do_something();
}
for _ in 1..10 {
if cond() {
continue;
do_something(); // $ Alert[rust/dead-code]
}
do_something();
}
loop {
if cond() {
return;
do_something(); // BAD: unreachable code
}
}
do_something(); // BAD: unreachable code
do_something();
do_something();
loop {
if cond() {
return;
do_something(); // $ Alert[rust/dead-code]
}
}
do_something(); // $ Alert[rust/dead-code]
do_something();
do_something();
}
fn unreachable_paren() {
let _ = (((1)));
let _ = (1);
}
fn unreachable_let_1() {
if let Some(_) = maybe_get_a_number() {
do_something();
return;
} else {
do_something();
}
if let Some(_) = maybe_get_a_number() {
do_something();
return;
} else {
do_something();
}
do_something();
do_something();
if let _ = get_a_number() { // (always succeeds)
do_something();
return;
} else {
do_something(); // BAD: unreachable code
}
if let _ = get_a_number() {
// (always succeeds)
do_something();
return;
} else {
do_something(); // $ Alert[rust/dead-code]
}
do_something();
do_something();
}
fn unreachable_let_2() {
let Some(_) = maybe_get_a_number() else {
do_something();
return;
};
let Some(_) = maybe_get_a_number() else {
do_something();
return;
};
do_something();
do_something();
let _ = maybe_get_a_number() else { // (always succeeds)
do_something(); // BAD: unreachable code
return;
};
let _ = maybe_get_a_number() else {
// (always succeeds)
do_something(); // $ Alert[rust/dead-code]
return;
};
do_something();
do_something();
}
fn unreachable_if_2() {
if cond() {
do_something();
return;
} else {
do_something();
}
if cond() {
do_something();
return;
} else {
do_something();
}
do_something();
do_something();
}
fn unreachable_if_3() {
if !cond() {
do_something();
return;
}
if !cond() {
do_something();
return;
}
do_something();
do_something();
}

View File

@@ -0,0 +1,21 @@
/**
* @kind test-postprocess
*/
private import rust
private import codeql.util.test.InlineExpectationsTest as T
private import internal.InlineExpectationsTestImpl
import T::TestPostProcessing
import T::TestPostProcessing::Make<Impl, Input>
private module Input implements T::TestPostProcessing::InputSig<Impl> {
string getRelativeUrl(Location location) {
exists(File f, int startline, int startcolumn, int endline, int endcolumn |
location.hasLocationInfo(_, startline, startcolumn, endline, endcolumn) and
f = location.getFile()
|
result =
f.getRelativePath() + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
)
}
}