Rust: Fix control flow tree for function and block expression

This commit is contained in:
Simon Friis Vindum
2024-09-11 11:16:06 +02:00
parent 809d040528
commit 857edb791c
6 changed files with 123 additions and 16 deletions

View File

@@ -4,8 +4,8 @@ private import rust
private import internal.ControlFlowGraphImpl
private import internal.Completion
private import internal.SuccessorType
private import codeql.rust.controlflow.BasicBlocks
private import internal.Scope as Scope
private import BasicBlocks
final class CfgScope = Scope::CfgScope;

View File

@@ -63,18 +63,17 @@ module CfgImpl = Make<Location, CfgInput>;
import CfgImpl
class FunctionTree extends LeafTree instanceof Function { }
class FunctionTree extends StandardPostOrderTree instanceof Function {
override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getBody() }
}
class BlockExprTree extends StandardPostOrderTree instanceof BlockExpr {
override ControlFlowTree getChildNode(int i) {
result = super.getStatement(i)
or
exists(int last |
last + 1 = i and
exists(super.getStatement(last)) and
not exists(super.getStatement(last + 1)) and
result = super.getTail()
)
not exists(super.getStatement(i)) and
(exists(super.getStatement(i - 1)) or i = 0) and
result = super.getTail()
}
}
@@ -123,3 +122,8 @@ class LetExprTree extends StandardPostOrderTree instanceof LetExpr {
}
class LiteralExprTree extends LeafTree instanceof LiteralExpr { }
class PathExprTree extends LeafTree instanceof PathExpr { }
// A leaf tree for unimplemented nodes in the AST.
class UnimplementedTree extends LeafTree instanceof Unimplemented { }

View File

@@ -8,9 +8,8 @@
*/
private import codeql.rust.elements.File
private import codeql.rust.controlflow.internal.ControlFlowGraphImpl
private import codeql.rust.controlflow.ControlFlowGraph
private import codeql.rust.controlflow.internal.ControlFlowGraphImpl as Impl
private import codeql.rust.controlflow.internal.ControlFlowGraphImplSpecific
/**
* Gets the source file to generate a CFG from.
@@ -33,7 +32,7 @@ external int selectedSourceColumn();
private predicate selectedSourceColumnAlias = selectedSourceColumn/0;
private module ViewCfgQueryInput implements Impl::ViewCfgQueryInputSig<File> {
private module ViewCfgQueryInput implements ViewCfgQueryInputSig<File> {
predicate selectedSourceFile = selectedSourceFileAlias/0;
predicate selectedSourceLine = selectedSourceLineAlias/0;
@@ -41,11 +40,11 @@ private module ViewCfgQueryInput implements Impl::ViewCfgQueryInputSig<File> {
predicate selectedSourceColumn = selectedSourceColumnAlias/0;
predicate cfgScopeSpan(
CfgInput::CfgScope scope, File file, int startLine, int startColumn, int endLine, int endColumn
CfgScope scope, File file, int startLine, int startColumn, int endLine, int endColumn
) {
file = scope.getFile() and
scope.getLocation().hasLocationInfo(_, startLine, startColumn, endLine, endColumn)
}
}
import Impl::ViewCfgQuery<File, ViewCfgQueryInput>
import ViewCfgQuery<File, ViewCfgQueryInput>

View File

@@ -0,0 +1,92 @@
nodes
| test.rs:1:1:7:1 | enter main | semmle.order | 1 |
| test.rs:1:1:7:1 | exit main | semmle.order | 2 |
| test.rs:1:1:7:1 | exit main (normal) | semmle.order | 3 |
| test.rs:1:1:7:1 | main | semmle.order | 4 |
| test.rs:1:18:7:1 | BlockExpr | semmle.order | 5 |
| test.rs:2:5:6:5 | IfExpr | semmle.order | 6 |
| test.rs:2:8:2:12 | LiteralExpr | semmle.order | 7 |
| test.rs:2:8:2:21 | BinaryOpExpr | semmle.order | 8 |
| test.rs:2:17:2:21 | LiteralExpr | semmle.order | 9 |
| test.rs:2:23:4:5 | BlockExpr | semmle.order | 10 |
| test.rs:3:9:3:20 | CallExpr | semmle.order | 11 |
| test.rs:3:19:3:19 | LiteralExpr | semmle.order | 12 |
| test.rs:4:12:6:5 | BlockExpr | semmle.order | 13 |
| test.rs:5:9:5:20 | CallExpr | semmle.order | 14 |
| test.rs:5:19:5:19 | LiteralExpr | semmle.order | 15 |
| test.rs:9:1:16:1 | decrement | semmle.order | 16 |
| test.rs:9:1:16:1 | enter decrement | semmle.order | 17 |
| test.rs:9:1:16:1 | exit decrement | semmle.order | 18 |
| test.rs:9:1:16:1 | exit decrement (normal) | semmle.order | 19 |
| test.rs:9:29:16:1 | BlockExpr | semmle.order | 20 |
| test.rs:11:5:15:5 | IfExpr | semmle.order | 21 |
| test.rs:11:8:11:8 | PathExpr | semmle.order | 22 |
| test.rs:11:8:11:13 | BinaryOpExpr | semmle.order | 23 |
| test.rs:11:13:11:13 | LiteralExpr | semmle.order | 24 |
| test.rs:11:15:13:5 | BlockExpr | semmle.order | 25 |
| test.rs:12:9:12:9 | LiteralExpr | semmle.order | 26 |
| test.rs:13:12:15:5 | BlockExpr | semmle.order | 27 |
| test.rs:14:9:14:9 | PathExpr | semmle.order | 28 |
| test.rs:14:9:14:13 | BinaryOpExpr | semmle.order | 29 |
| test.rs:14:13:14:13 | LiteralExpr | semmle.order | 30 |
edges
| test.rs:1:1:7:1 | enter main | test.rs:2:8:2:12 | LiteralExpr | semmle.label | |
| test.rs:1:1:7:1 | enter main | test.rs:2:8:2:12 | LiteralExpr | semmle.order | 1 |
| test.rs:1:1:7:1 | exit main (normal) | test.rs:1:1:7:1 | exit main | semmle.label | |
| test.rs:1:1:7:1 | exit main (normal) | test.rs:1:1:7:1 | exit main | semmle.order | 1 |
| test.rs:1:1:7:1 | main | test.rs:1:1:7:1 | exit main (normal) | semmle.label | |
| test.rs:1:1:7:1 | main | test.rs:1:1:7:1 | exit main (normal) | semmle.order | 1 |
| test.rs:1:18:7:1 | BlockExpr | test.rs:1:1:7:1 | main | semmle.label | |
| test.rs:1:18:7:1 | BlockExpr | test.rs:1:1:7:1 | main | semmle.order | 1 |
| test.rs:2:5:6:5 | IfExpr | test.rs:1:18:7:1 | BlockExpr | semmle.label | |
| test.rs:2:5:6:5 | IfExpr | test.rs:1:18:7:1 | BlockExpr | semmle.order | 1 |
| test.rs:2:8:2:12 | LiteralExpr | test.rs:2:17:2:21 | LiteralExpr | semmle.label | |
| test.rs:2:8:2:12 | LiteralExpr | test.rs:2:17:2:21 | LiteralExpr | semmle.order | 1 |
| test.rs:2:8:2:21 | BinaryOpExpr | test.rs:3:19:3:19 | LiteralExpr | semmle.label | true |
| test.rs:2:8:2:21 | BinaryOpExpr | test.rs:3:19:3:19 | LiteralExpr | semmle.order | 1 |
| test.rs:2:8:2:21 | BinaryOpExpr | test.rs:5:19:5:19 | LiteralExpr | semmle.label | false |
| test.rs:2:8:2:21 | BinaryOpExpr | test.rs:5:19:5:19 | LiteralExpr | semmle.order | 2 |
| test.rs:2:17:2:21 | LiteralExpr | test.rs:2:8:2:21 | BinaryOpExpr | semmle.label | |
| test.rs:2:17:2:21 | LiteralExpr | test.rs:2:8:2:21 | BinaryOpExpr | semmle.order | 1 |
| test.rs:2:23:4:5 | BlockExpr | test.rs:2:5:6:5 | IfExpr | semmle.label | |
| test.rs:2:23:4:5 | BlockExpr | test.rs:2:5:6:5 | IfExpr | semmle.order | 1 |
| test.rs:3:9:3:20 | CallExpr | test.rs:2:23:4:5 | BlockExpr | semmle.label | |
| test.rs:3:9:3:20 | CallExpr | test.rs:2:23:4:5 | BlockExpr | semmle.order | 1 |
| test.rs:3:19:3:19 | LiteralExpr | test.rs:3:9:3:20 | CallExpr | semmle.label | |
| test.rs:3:19:3:19 | LiteralExpr | test.rs:3:9:3:20 | CallExpr | semmle.order | 1 |
| test.rs:4:12:6:5 | BlockExpr | test.rs:2:5:6:5 | IfExpr | semmle.label | |
| test.rs:4:12:6:5 | BlockExpr | test.rs:2:5:6:5 | IfExpr | semmle.order | 1 |
| test.rs:5:9:5:20 | CallExpr | test.rs:4:12:6:5 | BlockExpr | semmle.label | |
| test.rs:5:9:5:20 | CallExpr | test.rs:4:12:6:5 | BlockExpr | semmle.order | 1 |
| test.rs:5:19:5:19 | LiteralExpr | test.rs:5:9:5:20 | CallExpr | semmle.label | |
| test.rs:5:19:5:19 | LiteralExpr | test.rs:5:9:5:20 | CallExpr | semmle.order | 1 |
| test.rs:9:1:16:1 | decrement | test.rs:9:1:16:1 | exit decrement (normal) | semmle.label | |
| test.rs:9:1:16:1 | decrement | test.rs:9:1:16:1 | exit decrement (normal) | semmle.order | 1 |
| test.rs:9:1:16:1 | enter decrement | test.rs:11:8:11:8 | PathExpr | semmle.label | |
| test.rs:9:1:16:1 | enter decrement | test.rs:11:8:11:8 | PathExpr | semmle.order | 1 |
| test.rs:9:1:16:1 | exit decrement (normal) | test.rs:9:1:16:1 | exit decrement | semmle.label | |
| test.rs:9:1:16:1 | exit decrement (normal) | test.rs:9:1:16:1 | exit decrement | semmle.order | 1 |
| test.rs:9:29:16:1 | BlockExpr | test.rs:9:1:16:1 | decrement | semmle.label | |
| test.rs:9:29:16:1 | BlockExpr | test.rs:9:1:16:1 | decrement | semmle.order | 1 |
| test.rs:11:5:15:5 | IfExpr | test.rs:9:29:16:1 | BlockExpr | semmle.label | |
| test.rs:11:5:15:5 | IfExpr | test.rs:9:29:16:1 | BlockExpr | semmle.order | 1 |
| test.rs:11:8:11:8 | PathExpr | test.rs:11:13:11:13 | LiteralExpr | semmle.label | |
| test.rs:11:8:11:8 | PathExpr | test.rs:11:13:11:13 | LiteralExpr | semmle.order | 1 |
| test.rs:11:8:11:13 | BinaryOpExpr | test.rs:12:9:12:9 | LiteralExpr | semmle.label | true |
| test.rs:11:8:11:13 | BinaryOpExpr | test.rs:12:9:12:9 | LiteralExpr | semmle.order | 1 |
| test.rs:11:8:11:13 | BinaryOpExpr | test.rs:14:9:14:9 | PathExpr | semmle.label | false |
| test.rs:11:8:11:13 | BinaryOpExpr | test.rs:14:9:14:9 | PathExpr | semmle.order | 2 |
| test.rs:11:13:11:13 | LiteralExpr | test.rs:11:8:11:13 | BinaryOpExpr | semmle.label | |
| test.rs:11:13:11:13 | LiteralExpr | test.rs:11:8:11:13 | BinaryOpExpr | semmle.order | 1 |
| test.rs:11:15:13:5 | BlockExpr | test.rs:11:5:15:5 | IfExpr | semmle.label | |
| test.rs:11:15:13:5 | BlockExpr | test.rs:11:5:15:5 | IfExpr | semmle.order | 1 |
| test.rs:12:9:12:9 | LiteralExpr | test.rs:11:15:13:5 | BlockExpr | semmle.label | |
| test.rs:12:9:12:9 | LiteralExpr | test.rs:11:15:13:5 | BlockExpr | semmle.order | 1 |
| test.rs:13:12:15:5 | BlockExpr | test.rs:11:5:15:5 | IfExpr | semmle.label | |
| test.rs:13:12:15:5 | BlockExpr | test.rs:11:5:15:5 | IfExpr | semmle.order | 1 |
| test.rs:14:9:14:9 | PathExpr | test.rs:14:13:14:13 | LiteralExpr | semmle.label | |
| test.rs:14:9:14:9 | PathExpr | test.rs:14:13:14:13 | LiteralExpr | semmle.order | 1 |
| test.rs:14:9:14:13 | BinaryOpExpr | test.rs:13:12:15:5 | BlockExpr | semmle.label | |
| test.rs:14:9:14:13 | BinaryOpExpr | test.rs:13:12:15:5 | BlockExpr | semmle.order | 1 |
| test.rs:14:13:14:13 | LiteralExpr | test.rs:14:9:14:13 | BinaryOpExpr | semmle.label | |
| test.rs:14:13:14:13 | LiteralExpr | test.rs:14:9:14:13 | BinaryOpExpr | semmle.order | 1 |

View File

@@ -4,8 +4,11 @@
import rust
import codeql.rust.controlflow.ControlFlowGraph
import TestUtils
class MyRelevantNode extends CfgNode {
MyRelevantNode() { toBeTested(this.getScope()) }
string getOrderDisambiguation() { result = "" }
}

View File

@@ -1,7 +1,16 @@
fn main() {
fn main() -> i64 {
if "foo" == "bar" {
println!("foobar");
decrement(0)
} else {
println!("baz")
decrement(5)
}
}
fn decrement(n: i64) -> i64 {
12;
if n == 0 {
0
} else {
n - 1
}
}