Skip to content

Commit

Permalink
Fix control flow tree for function and block expression
Browse files Browse the repository at this point in the history
  • Loading branch information
paldepind committed Sep 11, 2024
1 parent 809d040 commit 1126dc4
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 16 deletions.
2 changes: 1 addition & 1 deletion rust/ql/lib/codeql/rust/controlflow/ControlFlowGraph.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}

Expand Down Expand Up @@ -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 { }
9 changes: 4 additions & 5 deletions rust/ql/lib/codeql/rust/controlflow/internal/PrintCfg.ql
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -33,19 +32,19 @@ 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;

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>
92 changes: 92 additions & 0 deletions rust/ql/test/library-tests/controlflow/Cfg.expected
Original file line number Diff line number Diff line change
@@ -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 |
3 changes: 3 additions & 0 deletions rust/ql/test/library-tests/controlflow/Cfg.ql
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

import rust
import codeql.rust.controlflow.ControlFlowGraph
import TestUtils

class MyRelevantNode extends CfgNode {
MyRelevantNode() { toBeTested(this.getScope()) }

string getOrderDisambiguation() { result = "" }
}

Expand Down
15 changes: 12 additions & 3 deletions rust/ql/test/library-tests/controlflow/test.rs
Original file line number Diff line number Diff line change
@@ -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
}
}

0 comments on commit 1126dc4

Please sign in to comment.