Rust: Restrict 'unreachable' to nodes intended to be part of the CFG.

This commit is contained in:
Geoffrey White
2024-10-09 15:36:58 +01:00
parent 70d530a49c
commit f171eeb229
4 changed files with 21 additions and 33 deletions

View File

@@ -17,7 +17,12 @@ import codeql.rust.controlflow.internal.ControlFlowGraphImpl as ControlFlowGraph
*/
private predicate unreachable(AstNode n) {
not n = any(CfgNode cfn).getAstNode() and // reachable nodes
n instanceof ControlFlowGraphImpl::ControlFlowTree // part of the CFG
exists(ControlFlowGraphImpl::ControlFlowTree cft |
// nodes intended to be part of the CFG
cft.succ(n, _, _)
or
cft.succ(_, n, _)
)
}
/**

View File

@@ -1,31 +1,14 @@
| main.rs:216:9:217:9 | MatchArm | This code is never reached. |
| main.rs:218:9:219:9 | MatchArm | This code is never reached. |
| main.rs:224:9:226:9 | MatchArm | This code is never reached. |
| main.rs:227:9:228:9 | MatchArm | This code is never reached. |
| main.rs:233:9:234:9 | MatchArm | This code is never reached. |
| main.rs:235:9:235:28 | MatchArm | This code is never reached. |
| main.rs:240:9:240:26 | MatchArm | This code is never reached. |
| main.rs:241:9:241:25 | MatchArm | This code is never reached. |
| unreachable.rs:12:3:12:17 | ExprStmt | This code is never reached. |
| unreachable.rs:20:3:20:17 | ExprStmt | This code is never reached. |
| 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:46:6:46:8 | ParenExpr | This code is never reached. |
| unreachable.rs:48:7:48:10 | ParenExpr | This code is never reached. |
| unreachable.rs:60:2:60:16 | ExprStmt | This code is never reached. |
| unreachable.rs:101:3:101:17 | ExprStmt | This code is never reached. |
| unreachable.rs:109:3:109:17 | ExprStmt | This code is never reached. |
| unreachable.rs:117:3:119:3 | MatchArm | This code is never reached. |
| unreachable.rs:120:3:122:3 | MatchArm | This code is never reached. |
| unreachable.rs:124:2:124:16 | ExprStmt | This code is never reached. |
| unreachable.rs:127:3:129:3 | MatchArm | This code is never reached. |
| unreachable.rs:130:3:132:3 | MatchArm | 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:171:10:171:16 | ParenExpr | This code is never reached. |
| unreachable.rs:171:11:171:15 | ParenExpr | This code is never reached. |
| unreachable.rs:171:12:171:14 | ParenExpr | This code is never reached. |

View File

@@ -213,32 +213,32 @@ fn if_lets() {
let c = Some(60);
match c {
Some(val) => { // BAD: unused variable SPURIOUS: unreachable
Some(val) => { // BAD: unused variable
}
None => { // SPURIOUS: unused variable 'None', unreachable
None => { // SPURIOUS: unused variable 'None'
}
}
let d = Some(70);
match d {
Some(val) => { // SPURIOUS: unreachable
Some(val) => {
total += val;
}
None => { // SPURIOUS: unused variable 'None', unreachable
None => { // SPURIOUS: unused variable 'None'
}
}
let e = MyOption::Some(80);
match e {
MyOption::Some(val) => { // BAD: unused variable, unreachable
MyOption::Some(val) => { // BAD: unused variable
}
MyOption::None => {} // SPURIOUS: unreachable
MyOption::None => {}
}
let f = YesOrNo::Yes;
match f {
YesOrNo::Yes => {} // SPURIOUS: unreachable
YesOrNo::No => {} // SPURIOUS: unreachable
YesOrNo::Yes => {}
YesOrNo::No => {}
}
}

View File

@@ -43,9 +43,9 @@ fn unreachable_if() {
if cond() {
let x = cond();
if (x) { // SPURIOUS: unreachable
if (x) {
do_something();
if (!x) { // SPURIOUS: unreachable
if (!x) {
do_something(); // BAD: unreachable code [NOT DETECTED]
}
do_something();
@@ -114,20 +114,20 @@ fn unreachable_panic() {
fn unreachable_match() {
match get_a_number() {
1=>{ // [unreachable FALSE POSITIVE]
1=>{
return;
}
_=>{ // [unreachable FALSE POSITIVE]
_=>{
do_something();
}
}
do_something(); // [unreachable FALSE POSITIVE]
match get_a_number() {
1=>{ // [unreachable FALSE POSITIVE]
1=>{
return;
}
_=>{ // [unreachable FALSE POSITIVE]
_=>{
return;
}
}
@@ -168,5 +168,5 @@ fn unreachable_loop() {
}
fn unreachable_paren() {
let _ = (((1))); // SPURIOUS: unreachable (x3)
let _ = (((1)));
}