mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge pull request #17497 from geoffw0/unusedvar
Rust: Placeholder queries for unused variable, unused value
This commit is contained in:
24
rust/ql/src/queries/unusedentities/UnusedValue.qhelp
Normal file
24
rust/ql/src/queries/unusedentities/UnusedValue.qhelp
Normal file
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>This rule finds values that are assigned to variables but never used. Unused values should be removed to increase readability and avoid confusion.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>Remove any unused values. Also remove any variables that only hold unused values.</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>In the following example, there is a variable <code>average</code> that is initialized to <code>0</code>, but that value is never used:</p>
|
||||
<sample src="UnusedValueBad.rs" />
|
||||
<p>The problem can be fixed by removing the unused value:</p>
|
||||
<sample src="UnusedValueGood.rs" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>GeeksforGeeks: <a href="https://www.geeksforgeeks.org/how-to-avoid-unused-variable-warning-in-rust/">How to avoid unused Variable warning in Rust?</a></li>
|
||||
</references>
|
||||
</qhelp>
|
||||
15
rust/ql/src/queries/unusedentities/UnusedValue.ql
Normal file
15
rust/ql/src/queries/unusedentities/UnusedValue.ql
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @name Unused value
|
||||
* @description Unused values may be an indication that the code is incomplete or has a typo.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id rust/unused-value
|
||||
* @tags maintainability
|
||||
*/
|
||||
|
||||
import rust
|
||||
|
||||
from Locatable e
|
||||
where none() // TODO: implement query
|
||||
select e, "Variable is assigned a value that is never used."
|
||||
11
rust/ql/src/queries/unusedentities/UnusedValueBad.rs
Normal file
11
rust/ql/src/queries/unusedentities/UnusedValueBad.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
fn get_average(values:&[i32]) -> f64 {
|
||||
let mut sum = 0;
|
||||
let mut average = 0.0; // BAD: unused value
|
||||
|
||||
for v in values {
|
||||
sum += v;
|
||||
}
|
||||
|
||||
average = sum as f64 / values.len() as f64;
|
||||
return average;
|
||||
}
|
||||
11
rust/ql/src/queries/unusedentities/UnusedValueGood.rs
Normal file
11
rust/ql/src/queries/unusedentities/UnusedValueGood.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
fn get_average(values:&[i32]) -> f64 {
|
||||
let mut sum = 0;
|
||||
let average;
|
||||
|
||||
for v in values {
|
||||
sum += v;
|
||||
}
|
||||
|
||||
average = sum as f64 / values.len() as f64;
|
||||
return average;
|
||||
}
|
||||
24
rust/ql/src/queries/unusedentities/UnusedVariable.qhelp
Normal file
24
rust/ql/src/queries/unusedentities/UnusedVariable.qhelp
Normal file
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>This rule finds variables that are never accessed. Unused variables should be removed to increase readability and avoid confusion.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>Remove any unused variables.</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>In the following example, there is an unused variable <code>average</code> that is never used:</p>
|
||||
<sample src="UnusedVariableBad.rs" />
|
||||
<p>The problem can be fixed simply by removing the variable:</p>
|
||||
<sample src="UnusedVariableGood.rs" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>GeeksforGeeks: <a href="https://www.geeksforgeeks.org/how-to-avoid-unused-variable-warning-in-rust/">How to avoid unused Variable warning in Rust?</a></li>
|
||||
</references>
|
||||
</qhelp>
|
||||
15
rust/ql/src/queries/unusedentities/UnusedVariable.ql
Normal file
15
rust/ql/src/queries/unusedentities/UnusedVariable.ql
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @name Unused variable
|
||||
* @description Unused variables may be an indication that the code is incomplete or has a typo.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @precision medium
|
||||
* @id rust/unused-variable
|
||||
* @tags maintainability
|
||||
*/
|
||||
|
||||
import rust
|
||||
|
||||
from Locatable e
|
||||
where none() // TODO: implement query
|
||||
select e, "Variable is not used."
|
||||
10
rust/ql/src/queries/unusedentities/UnusedVariableBad.rs
Normal file
10
rust/ql/src/queries/unusedentities/UnusedVariableBad.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
fn get_sum(values:&[i32]) -> i32 {
|
||||
let mut sum = 0;
|
||||
let mut average; // BAD: unused variable
|
||||
|
||||
for v in values {
|
||||
sum += v;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
9
rust/ql/src/queries/unusedentities/UnusedVariableGood.rs
Normal file
9
rust/ql/src/queries/unusedentities/UnusedVariableGood.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
fn get_sum(values:&[i32]) -> i32 {
|
||||
let mut sum = 0;
|
||||
|
||||
for v in values {
|
||||
sum += v;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
queries/unusedentities/UnusedValue.ql
|
||||
@@ -0,0 +1 @@
|
||||
queries/unusedentities/UnusedVariable.ql
|
||||
152
rust/ql/test/query-tests/unusedentities/main.rs
Normal file
152
rust/ql/test/query-tests/unusedentities/main.rs
Normal file
@@ -0,0 +1,152 @@
|
||||
|
||||
//fn cond() -> bool;
|
||||
|
||||
// --- locals ---
|
||||
|
||||
fn locals_1() {
|
||||
let a = 1; // BAD: unused value [NOT DETECTED]
|
||||
let b = 1;
|
||||
let c = 1;
|
||||
let d = String::from("a"); // BAD: unused value [NOT DETECTED]
|
||||
let e = String::from("b");
|
||||
let _ = 1; // (deliberately unused)
|
||||
|
||||
println!("use {}", b);
|
||||
|
||||
if cond() {
|
||||
println!("use {}", c);
|
||||
}
|
||||
|
||||
println!("use {}", e);
|
||||
}
|
||||
|
||||
fn locals_2() {
|
||||
let a: i32;
|
||||
let b: i32; // BAD: unused variable [NOT DETECTED]
|
||||
let mut c: i32;
|
||||
let mut d: i32;
|
||||
let mut e: i32;
|
||||
let mut f: i32;
|
||||
let g: i32;
|
||||
let h: i32;
|
||||
let i: i32;
|
||||
|
||||
b = 1; // BAD: unused value [NOT DETECTED]
|
||||
|
||||
c = 1; // BAD: unused value [NOT DETECTED]
|
||||
c = 2;
|
||||
println!("use {}", c);
|
||||
c = 3; // BAD: unused value [NOT DETECTED]
|
||||
|
||||
d = 1;
|
||||
if cond() {
|
||||
d = 2; // BAD: unused value [NOT DETECTED]
|
||||
d = 3;
|
||||
} else {
|
||||
}
|
||||
println!("use {}", d);
|
||||
|
||||
e = 1; // BAD: unused value [NOT DETECTED]
|
||||
if cond() {
|
||||
e = 2;
|
||||
} else {
|
||||
e = 3;
|
||||
}
|
||||
println!("use {}", e);
|
||||
|
||||
f = 1;
|
||||
f += 1;
|
||||
println!("use {}", f);
|
||||
f += 1; // BAD: unused value [NOT DETECTED]
|
||||
f = 1;
|
||||
f += 1; // BAD: unused value [NOT DETECTED]
|
||||
|
||||
g = if cond() { 1 } else { 2 }; // BAD: unused value (x2) [NOT DETECTED]
|
||||
h = if cond() { 3 } else { 4 };
|
||||
i = if cond() { h } else { 5 };
|
||||
println!("use {}", i);
|
||||
|
||||
_ = 1; // (deliberately unused) [NOT DETECTED]
|
||||
}
|
||||
|
||||
// --- structs ---
|
||||
|
||||
#[derive(Debug)]
|
||||
struct MyStruct {
|
||||
val: i64
|
||||
}
|
||||
|
||||
impl MyStruct {
|
||||
fn my_get(&mut self) -> i64 {
|
||||
return self.val;
|
||||
}
|
||||
}
|
||||
|
||||
fn structs() {
|
||||
let a = MyStruct {val : 1 }; // BAD: unused value [NOT DETECTED]
|
||||
let b = MyStruct {val : 2 };
|
||||
let c = MyStruct {val : 3 };
|
||||
let mut d : MyStruct; // BAD: unused variable [NOT DETECTED]
|
||||
let mut e : MyStruct;
|
||||
let mut f : MyStruct;
|
||||
|
||||
println!("lets use {:?} and {}", b, c.val);
|
||||
|
||||
e = MyStruct {val : 4 };
|
||||
println!("lets use {}", e.my_get());
|
||||
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]
|
||||
}
|
||||
|
||||
// --- arrays ---
|
||||
|
||||
fn arrays() {
|
||||
let is = [1, 2, 3]; // BAD: unused values (x3) [NOT DETECTED]
|
||||
let js = [1, 2, 3];
|
||||
let ks = [1, 2, 3];
|
||||
|
||||
println!("lets use {:?}", js);
|
||||
|
||||
for k in ks {
|
||||
println!("lets use {}", k);
|
||||
}
|
||||
}
|
||||
|
||||
// --- constants and statics ---
|
||||
|
||||
const CON1: i32 = 1;
|
||||
const CON2: i32 = 2; // BAD: unused value [NOT DETECTED]
|
||||
static mut STAT1: i32 = 1;
|
||||
static mut STAT2: i32 = 2; // BAD: unused value [NOT DETECTED]
|
||||
|
||||
fn statics() {
|
||||
static mut STAT3: i32 = 0;
|
||||
static mut STAT4: i32 = 0; // BAD: unused value [NOT DETECTED]
|
||||
|
||||
unsafe
|
||||
{
|
||||
let total = CON1 + STAT1 + STAT3;
|
||||
}
|
||||
}
|
||||
|
||||
// --- parameters ---
|
||||
|
||||
fn parameters(
|
||||
x: i32,
|
||||
y: i32, // BAD: unused variable [NOT DETECTED]
|
||||
_z: i32 // (`_` is asking the compiler, and by extension us, to not warn that this is unused)
|
||||
) -> i32 {
|
||||
return x;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
locals_1();
|
||||
locals_2();
|
||||
structs();
|
||||
arrays();
|
||||
statics();
|
||||
println!("lets use result {}", parameters(1, 2, 3));
|
||||
}
|
||||
Reference in New Issue
Block a user