Skip to content

Commit

Permalink
Merge pull request #17865 from hvitved/rust/unused-macro-expansion
Browse files Browse the repository at this point in the history
  • Loading branch information
hvitved authored Nov 3, 2024
2 parents cec0544 + c4adec3 commit 662a824
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 92 deletions.
20 changes: 14 additions & 6 deletions rust/ql/lib/codeql/rust/elements/internal/AstNodeImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,29 @@ module Impl {
result = getImmediateParent(e)
}

/** Gets the nearest enclosing parent of `ast` that is an `AstNode`. */
private AstNode getParentOfAst(AstNode ast) {
result = getParentOfAstStep*(getImmediateParent(ast))
}

class AstNode extends Generated::AstNode {
/**
* Gets the nearest enclosing parent of this node, which is also an `AstNode`,
* if any.
*/
AstNode getParentNode() { result = getParentOfAstStep*(getImmediateParent(this)) }

/** Gets the immediately enclosing callable of this node, if any. */
cached
Callable getEnclosingCallable() {
exists(AstNode p | p = getParentOfAst(this) |
exists(AstNode p | p = this.getParentNode() |
result = p
or
not p instanceof Callable and
result = p.getEnclosingCallable()
)
}

/** Holds if this node is inside a macro expansion. */
predicate isInMacroExpansion() {
this = any(MacroCall mc).getExpanded()
or
this.getParentNode().isInMacroExpansion()
}
}
}
5 changes: 4 additions & 1 deletion rust/ql/src/queries/unusedentities/UnreachableCode.ql
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ predicate hiddenNode(AstNode n) {
not succ(n, _) and
not succ(_, n)
or
n instanceof ControlFlowGraphImpl::PostOrderTree // location is counter-intuitive
n instanceof ControlFlowGraphImpl::PostOrderTree and // location is counter-intuitive
not n instanceof MacroExpr
or
n.isInMacroExpansion()
}

/**
Expand Down
5 changes: 3 additions & 2 deletions rust/ql/src/queries/unusedentities/UnusedValue.ql
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ where
not write = any(Ssa::WriteDefinition def).getWriteAccess().getAstNode() and
// avoid overlap with the unused variable query
not isUnused(v) and
not v instanceof DiscardVariable
select write, "Variable is assigned a value that is never used."
not v instanceof DiscardVariable and
not write.isInMacroExpansion()
select write, "Variable $@ is assigned a value that is never used.", v, v.getName()
2 changes: 1 addition & 1 deletion rust/ql/src/queries/unusedentities/UnusedVariable.ql
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ import UnusedVariable

from Variable v
where isUnused(v)
select v, "Variable is not used."
select v, "Variable '" + v + "' is not used."
1 change: 1 addition & 0 deletions rust/ql/src/queries/unusedentities/UnusedVariable.qll
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ predicate isUnused(Variable v) {
not exists(v.getAnAccess()) and
not exists(v.getInitializer()) and
not v instanceof DiscardVariable and
not v.getPat().isInMacroExpansion() and
exists(File f | f.getBaseName() = "main.rs" | v.getLocation().getFile() = f) // temporarily severely limit results
}
28 changes: 14 additions & 14 deletions rust/ql/test/query-tests/unusedentities/UnreachableCode.expected
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
| 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:27:9:27:23 | ExprStmt | This code is never reached. |
| unreachable.rs:39:9:39:23 | ExprStmt | This code is never reached. |
| unreachable.rs:46:9:46:23 | ExprStmt | This code is never reached. |
| unreachable.rs:67:5:67:19 | ExprStmt | This code is never reached. |
| unreachable.rs:114:13:114:20 | MacroExpr | This code is never reached. |
| unreachable.rs:123:13:123:20 | MacroExpr | This code is never reached. |
| unreachable.rs:149:5:149:19 | ExprStmt | This code is never reached. |
| unreachable.rs:156:9:156:23 | ExprStmt | This code is never reached. |
| unreachable.rs:165:13:165:27 | ExprStmt | This code is never reached. |
| unreachable.rs:171:9:171:23 | 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. |
| unreachable.rs:185:13:185:27 | ExprStmt | This code is never reached. |
| unreachable.rs:188:5:188:19 | ExprStmt | This code is never reached. |
| unreachable.rs:212:9:212:23 | ExprStmt | This code is never reached. |
| unreachable.rs:228:9:228:23 | ExprStmt | This code is never reached. |
44 changes: 20 additions & 24 deletions rust/ql/test/query-tests/unusedentities/UnusedValue.expected
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
| main.rs:6:9:6:9 | a | Variable is assigned a value that is never used. |
| main.rs:9:9:9:9 | d | Variable is assigned a value that is never used. |
| main.rs:35:5:35:5 | b | Variable is assigned a value that is never used. |
| main.rs:37:5:37:5 | c | Variable is assigned a value that is never used. |
| main.rs:40:5:40:5 | c | Variable is assigned a value that is never used. |
| main.rs:44:9:44:9 | d | Variable is assigned a value that is never used. |
| main.rs:50:5:50:5 | e | Variable is assigned a value that is never used. |
| main.rs:61:5:61:5 | f | Variable is assigned a value that is never used. |
| main.rs:63:5:63:5 | f | Variable is assigned a value that is never used. |
| 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: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: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. |
| main.rs:8:9:8:9 | a | Variable $@ is assigned a value that is never used. | main.rs:8:9:8:9 | a | a |
| main.rs:11:9:11:9 | d | Variable $@ is assigned a value that is never used. | main.rs:11:9:11:9 | d | d |
| main.rs:37:5:37:5 | b | Variable $@ is assigned a value that is never used. | main.rs:28:9:28:9 | b | b |
| main.rs:39:5:39:5 | c | Variable $@ is assigned a value that is never used. | main.rs:29:13:29:13 | c | c |
| main.rs:42:5:42:5 | c | Variable $@ is assigned a value that is never used. | main.rs:29:13:29:13 | c | c |
| main.rs:46:9:46:9 | d | Variable $@ is assigned a value that is never used. | main.rs:30:13:30:13 | d | d |
| main.rs:52:5:52:5 | e | Variable $@ is assigned a value that is never used. | main.rs:31:13:31:13 | e | e |
| main.rs:63:5:63:5 | f | Variable $@ is assigned a value that is never used. | main.rs:32:13:32:13 | f | f |
| main.rs:65:5:65:5 | f | Variable $@ is assigned a value that is never used. | main.rs:32:13:32:13 | f | f |
| main.rs:67:5:67:5 | g | Variable $@ is assigned a value that is never used. | main.rs:33:9:33:9 | g | g |
| main.rs:89:9:89:9 | a | Variable $@ is assigned a value that is never used. | main.rs:89:9:89:9 | a | a |
| main.rs:110:9:110:10 | is | Variable $@ is assigned a value that is never used. | main.rs:110:9:110:10 | is | is |
| main.rs:133:13:133:17 | total | Variable $@ is assigned a value that is never used. | main.rs:133:13:133:17 | total | total |
| main.rs:270:13:270:17 | total | Variable $@ is assigned a value that is never used. | main.rs:238:13:238:17 | total | total |
| main.rs:363:9:363:9 | x | Variable $@ is assigned a value that is never used. | main.rs:363:9:363:9 | x | x |
| main.rs:371:17:371:17 | x | Variable $@ is assigned a value that is never used. | main.rs:371:17:371:17 | x | x |
| more.rs:24:9:24:11 | val | Variable $@ is assigned a value that is never used. | more.rs:24:9:24:11 | val | val |
| more.rs:44:9:44:14 | a_ptr4 | Variable $@ is assigned a value that is never used. | more.rs:44:9:44:14 | a_ptr4 | a_ptr4 |
| more.rs:59:9:59:13 | d_ptr | Variable $@ is assigned a value that is never used. | more.rs:59:9:59:13 | d_ptr | d_ptr |
| more.rs:65:9:65:17 | f_ptr | Variable $@ is assigned a value that is never used. | more.rs:65:13:65:17 | f_ptr | f_ptr |
42 changes: 21 additions & 21 deletions rust/ql/test/query-tests/unusedentities/UnusedVariable.expected
Original file line number Diff line number Diff line change
@@ -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: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. |
| main.rs:27:9:27:9 | a | Variable 'a' is not used. |
| main.rs:92:13:92:13 | d | Variable 'd' is not used. |
| main.rs:141:5:141:5 | y | Variable 'y' is not used. |
| main.rs:168:9:168:9 | x | Variable 'x' is not used. |
| main.rs:240:17:240:17 | a | Variable 'a' is not used. |
| main.rs:248:20:248:22 | val | Variable 'val' is not used. |
| main.rs:262:14:262:16 | val | Variable 'val' is not used. |
| main.rs:277:22:277:24 | val | Variable 'val' is not used. |
| main.rs:284:24:284:26 | val | Variable 'val' is not used. |
| main.rs:292:13:292:15 | num | Variable 'num' is not used. |
| main.rs:307:12:307:12 | j | Variable 'j' is not used. |
| main.rs:327:25:327:25 | y | Variable 'y' is not used. |
| main.rs:330:28:330:28 | a | Variable 'a' is not used. |
| main.rs:333:9:333:9 | p | Variable 'p' is not used. |
| main.rs:351:9:351:13 | right | Variable 'right' is not used. |
| main.rs:357:9:357:14 | right2 | Variable 'right2' is not used. |
| main.rs:364:13:364:13 | y | Variable 'y' is not used. |
| main.rs:372:21:372:21 | y | Variable 'y' is not used. |
| main.rs:417:26:417:28 | val | Variable 'val' is not used. |
| main.rs:420:21:420:23 | acc | Variable 'acc' is not used. |
| main.rs:441:9:441:14 | unused | Variable 'unused' is not used. |
39 changes: 29 additions & 10 deletions rust/ql/test/query-tests/unusedentities/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//fn cond() -> bool;
mod unreachable;

use unreachable::*;

// --- locals ---

Expand Down Expand Up @@ -191,7 +193,7 @@ fn loops() {
}

for x in 1..10 {
_ = format!("x is {x}"); // $ SPURIOUS: Alert[rust/unused-value]
_ = format!("x is {x}");
}

for x in 1..10 {
Expand All @@ -203,11 +205,13 @@ fn loops() {
}

for x in 1..10 {
assert_eq!(x, 1); // $ SPURIOUS: Alert[rust/unused-value]
assert_eq!(x, 1);
break;
}

for x in 1..10 {
assert_eq!(id(x), id(1)); // $ SPURIOUS: Alert[rust/unused-value]
assert_eq!(id(x), id(1));
break;
}
}

Expand Down Expand Up @@ -331,7 +335,7 @@ fn if_lets_matches() {
}

let duration1 = std::time::Duration::new(10, 0); // ten seconds
assert_eq!(duration1.as_secs(), 10); // $ SPURIOUS: Alert[rust/unused-value]
assert_eq!(duration1.as_secs(), 10);

let duration2: Result<std::time::Duration, String> = Ok(std::time::Duration::new(10, 0));
match duration2 {
Expand Down Expand Up @@ -434,7 +438,7 @@ impl Incrementable for MyValue {
fn increment(
&mut self,
times: i32,
unused: i32, // $ Alert[rust/unused-variable]
unused: &mut i32, // $ Alert[rust/unused-variable]
) {
self.value += times;
}
Expand All @@ -443,9 +447,22 @@ impl Incrementable for MyValue {
fn traits() {
let mut i = MyValue { value: 0 };
let a = 1;
let b = 2;
let mut b = 2;

i.increment(a, &mut b);
}

i.increment(a, b);
// --- macros ---

fn macros() {
let x;
println!(
"The value of x is {}",
({
x = 10; // $ MISSING: Alert[rust/unused-value]
10
})
)
}

// --- main ---
Expand All @@ -464,12 +481,14 @@ fn main() {
folds_and_closures();

unreachable_if_1();
unreachable_panic();
// unreachable_panic();
unreachable_match();
unreachable_loop();
// unreachable_loop();
unreachable_paren();
unreachable_let_1();
unreachable_let_2();
unreachable_if_2();
unreachable_if_3();

macros();
}
1 change: 0 additions & 1 deletion rust/ql/test/query-tests/unusedentities/options

This file was deleted.

32 changes: 20 additions & 12 deletions rust/ql/test/query-tests/unusedentities/unreachable.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
//fn cond() -> bool;
//fn get_a_number() -> i32;
//fn maybe_get_a_number() -> Option<i32>;
pub fn cond() -> bool {
get_a_number() == 1
}

fn get_a_number() -> i32 {
maybe_get_a_number().unwrap_or(0)
}

fn maybe_get_a_number() -> Option<i32> {
std::env::args().nth(1).map(|s| s.parse::<i32>().unwrap())
}

// --- unreachable code --

fn do_something() {}

fn unreachable_if_1() {
pub fn unreachable_if_1() {
if false {
do_something(); // $ Alert[rust/dead-code]
} else {
Expand Down Expand Up @@ -59,7 +67,7 @@ fn unreachable_if_1() {
do_something(); // $ Alert[rust/dead-code]
}

fn unreachable_panic() {
pub fn unreachable_panic() {
if cond() {
do_something();
panic!("Oh no!!!");
Expand Down Expand Up @@ -119,7 +127,7 @@ fn unreachable_panic() {
}
}

fn unreachable_match() {
pub fn unreachable_match() {
match get_a_number() {
1 => {
return;
Expand All @@ -141,7 +149,7 @@ fn unreachable_match() {
do_something(); // $ Alert[rust/dead-code]
}

fn unreachable_loop() {
pub fn unreachable_loop() {
loop {
do_something();
break;
Expand Down Expand Up @@ -182,11 +190,11 @@ fn unreachable_loop() {
do_something();
}

fn unreachable_paren() {
pub fn unreachable_paren() {
let _ = (((1)));
}

fn unreachable_let_1() {
pub fn unreachable_let_1() {
if let Some(_) = maybe_get_a_number() {
do_something();
return;
Expand All @@ -207,7 +215,7 @@ fn unreachable_let_1() {
do_something();
}

fn unreachable_let_2() {
pub fn unreachable_let_2() {
let Some(_) = maybe_get_a_number() else {
do_something();
return;
Expand All @@ -224,7 +232,7 @@ fn unreachable_let_2() {
do_something();
}

fn unreachable_if_2() {
pub fn unreachable_if_2() {
if cond() {
do_something();
return;
Expand All @@ -235,7 +243,7 @@ fn unreachable_if_2() {
do_something();
}

fn unreachable_if_3() {
pub fn unreachable_if_3() {
if !cond() {
do_something();
return;
Expand Down

0 comments on commit 662a824

Please sign in to comment.