Skip to content

Commit 857edb7

Browse files
committed
Rust: Fix control flow tree for function and block expression
1 parent 809d040 commit 857edb7

File tree

6 files changed

+123
-16
lines changed

6 files changed

+123
-16
lines changed

rust/ql/lib/codeql/rust/controlflow/ControlFlowGraph.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ private import rust
44
private import internal.ControlFlowGraphImpl
55
private import internal.Completion
66
private import internal.SuccessorType
7-
private import codeql.rust.controlflow.BasicBlocks
87
private import internal.Scope as Scope
8+
private import BasicBlocks
99

1010
final class CfgScope = Scope::CfgScope;
1111

rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,17 @@ module CfgImpl = Make<Location, CfgInput>;
6363

6464
import CfgImpl
6565

66-
class FunctionTree extends LeafTree instanceof Function { }
66+
class FunctionTree extends StandardPostOrderTree instanceof Function {
67+
override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getBody() }
68+
}
6769

6870
class BlockExprTree extends StandardPostOrderTree instanceof BlockExpr {
6971
override ControlFlowTree getChildNode(int i) {
7072
result = super.getStatement(i)
7173
or
72-
exists(int last |
73-
last + 1 = i and
74-
exists(super.getStatement(last)) and
75-
not exists(super.getStatement(last + 1)) and
76-
result = super.getTail()
77-
)
74+
not exists(super.getStatement(i)) and
75+
(exists(super.getStatement(i - 1)) or i = 0) and
76+
result = super.getTail()
7877
}
7978
}
8079

@@ -123,3 +122,8 @@ class LetExprTree extends StandardPostOrderTree instanceof LetExpr {
123122
}
124123

125124
class LiteralExprTree extends LeafTree instanceof LiteralExpr { }
125+
126+
class PathExprTree extends LeafTree instanceof PathExpr { }
127+
128+
// A leaf tree for unimplemented nodes in the AST.
129+
class UnimplementedTree extends LeafTree instanceof Unimplemented { }

rust/ql/lib/codeql/rust/controlflow/internal/PrintCfg.ql

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88
*/
99

1010
private import codeql.rust.elements.File
11+
private import codeql.rust.controlflow.internal.ControlFlowGraphImpl
1112
private import codeql.rust.controlflow.ControlFlowGraph
12-
private import codeql.rust.controlflow.internal.ControlFlowGraphImpl as Impl
13-
private import codeql.rust.controlflow.internal.ControlFlowGraphImplSpecific
1413

1514
/**
1615
* Gets the source file to generate a CFG from.
@@ -33,19 +32,19 @@ external int selectedSourceColumn();
3332

3433
private predicate selectedSourceColumnAlias = selectedSourceColumn/0;
3534

36-
private module ViewCfgQueryInput implements Impl::ViewCfgQueryInputSig<File> {
35+
private module ViewCfgQueryInput implements ViewCfgQueryInputSig<File> {
3736
predicate selectedSourceFile = selectedSourceFileAlias/0;
3837

3938
predicate selectedSourceLine = selectedSourceLineAlias/0;
4039

4140
predicate selectedSourceColumn = selectedSourceColumnAlias/0;
4241

4342
predicate cfgScopeSpan(
44-
CfgInput::CfgScope scope, File file, int startLine, int startColumn, int endLine, int endColumn
43+
CfgScope scope, File file, int startLine, int startColumn, int endLine, int endColumn
4544
) {
4645
file = scope.getFile() and
4746
scope.getLocation().hasLocationInfo(_, startLine, startColumn, endLine, endColumn)
4847
}
4948
}
5049

51-
import Impl::ViewCfgQuery<File, ViewCfgQueryInput>
50+
import ViewCfgQuery<File, ViewCfgQueryInput>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
nodes
2+
| test.rs:1:1:7:1 | enter main | semmle.order | 1 |
3+
| test.rs:1:1:7:1 | exit main | semmle.order | 2 |
4+
| test.rs:1:1:7:1 | exit main (normal) | semmle.order | 3 |
5+
| test.rs:1:1:7:1 | main | semmle.order | 4 |
6+
| test.rs:1:18:7:1 | BlockExpr | semmle.order | 5 |
7+
| test.rs:2:5:6:5 | IfExpr | semmle.order | 6 |
8+
| test.rs:2:8:2:12 | LiteralExpr | semmle.order | 7 |
9+
| test.rs:2:8:2:21 | BinaryOpExpr | semmle.order | 8 |
10+
| test.rs:2:17:2:21 | LiteralExpr | semmle.order | 9 |
11+
| test.rs:2:23:4:5 | BlockExpr | semmle.order | 10 |
12+
| test.rs:3:9:3:20 | CallExpr | semmle.order | 11 |
13+
| test.rs:3:19:3:19 | LiteralExpr | semmle.order | 12 |
14+
| test.rs:4:12:6:5 | BlockExpr | semmle.order | 13 |
15+
| test.rs:5:9:5:20 | CallExpr | semmle.order | 14 |
16+
| test.rs:5:19:5:19 | LiteralExpr | semmle.order | 15 |
17+
| test.rs:9:1:16:1 | decrement | semmle.order | 16 |
18+
| test.rs:9:1:16:1 | enter decrement | semmle.order | 17 |
19+
| test.rs:9:1:16:1 | exit decrement | semmle.order | 18 |
20+
| test.rs:9:1:16:1 | exit decrement (normal) | semmle.order | 19 |
21+
| test.rs:9:29:16:1 | BlockExpr | semmle.order | 20 |
22+
| test.rs:11:5:15:5 | IfExpr | semmle.order | 21 |
23+
| test.rs:11:8:11:8 | PathExpr | semmle.order | 22 |
24+
| test.rs:11:8:11:13 | BinaryOpExpr | semmle.order | 23 |
25+
| test.rs:11:13:11:13 | LiteralExpr | semmle.order | 24 |
26+
| test.rs:11:15:13:5 | BlockExpr | semmle.order | 25 |
27+
| test.rs:12:9:12:9 | LiteralExpr | semmle.order | 26 |
28+
| test.rs:13:12:15:5 | BlockExpr | semmle.order | 27 |
29+
| test.rs:14:9:14:9 | PathExpr | semmle.order | 28 |
30+
| test.rs:14:9:14:13 | BinaryOpExpr | semmle.order | 29 |
31+
| test.rs:14:13:14:13 | LiteralExpr | semmle.order | 30 |
32+
edges
33+
| test.rs:1:1:7:1 | enter main | test.rs:2:8:2:12 | LiteralExpr | semmle.label | |
34+
| test.rs:1:1:7:1 | enter main | test.rs:2:8:2:12 | LiteralExpr | semmle.order | 1 |
35+
| test.rs:1:1:7:1 | exit main (normal) | test.rs:1:1:7:1 | exit main | semmle.label | |
36+
| test.rs:1:1:7:1 | exit main (normal) | test.rs:1:1:7:1 | exit main | semmle.order | 1 |
37+
| test.rs:1:1:7:1 | main | test.rs:1:1:7:1 | exit main (normal) | semmle.label | |
38+
| test.rs:1:1:7:1 | main | test.rs:1:1:7:1 | exit main (normal) | semmle.order | 1 |
39+
| test.rs:1:18:7:1 | BlockExpr | test.rs:1:1:7:1 | main | semmle.label | |
40+
| test.rs:1:18:7:1 | BlockExpr | test.rs:1:1:7:1 | main | semmle.order | 1 |
41+
| test.rs:2:5:6:5 | IfExpr | test.rs:1:18:7:1 | BlockExpr | semmle.label | |
42+
| test.rs:2:5:6:5 | IfExpr | test.rs:1:18:7:1 | BlockExpr | semmle.order | 1 |
43+
| test.rs:2:8:2:12 | LiteralExpr | test.rs:2:17:2:21 | LiteralExpr | semmle.label | |
44+
| test.rs:2:8:2:12 | LiteralExpr | test.rs:2:17:2:21 | LiteralExpr | semmle.order | 1 |
45+
| test.rs:2:8:2:21 | BinaryOpExpr | test.rs:3:19:3:19 | LiteralExpr | semmle.label | true |
46+
| test.rs:2:8:2:21 | BinaryOpExpr | test.rs:3:19:3:19 | LiteralExpr | semmle.order | 1 |
47+
| test.rs:2:8:2:21 | BinaryOpExpr | test.rs:5:19:5:19 | LiteralExpr | semmle.label | false |
48+
| test.rs:2:8:2:21 | BinaryOpExpr | test.rs:5:19:5:19 | LiteralExpr | semmle.order | 2 |
49+
| test.rs:2:17:2:21 | LiteralExpr | test.rs:2:8:2:21 | BinaryOpExpr | semmle.label | |
50+
| test.rs:2:17:2:21 | LiteralExpr | test.rs:2:8:2:21 | BinaryOpExpr | semmle.order | 1 |
51+
| test.rs:2:23:4:5 | BlockExpr | test.rs:2:5:6:5 | IfExpr | semmle.label | |
52+
| test.rs:2:23:4:5 | BlockExpr | test.rs:2:5:6:5 | IfExpr | semmle.order | 1 |
53+
| test.rs:3:9:3:20 | CallExpr | test.rs:2:23:4:5 | BlockExpr | semmle.label | |
54+
| test.rs:3:9:3:20 | CallExpr | test.rs:2:23:4:5 | BlockExpr | semmle.order | 1 |
55+
| test.rs:3:19:3:19 | LiteralExpr | test.rs:3:9:3:20 | CallExpr | semmle.label | |
56+
| test.rs:3:19:3:19 | LiteralExpr | test.rs:3:9:3:20 | CallExpr | semmle.order | 1 |
57+
| test.rs:4:12:6:5 | BlockExpr | test.rs:2:5:6:5 | IfExpr | semmle.label | |
58+
| test.rs:4:12:6:5 | BlockExpr | test.rs:2:5:6:5 | IfExpr | semmle.order | 1 |
59+
| test.rs:5:9:5:20 | CallExpr | test.rs:4:12:6:5 | BlockExpr | semmle.label | |
60+
| test.rs:5:9:5:20 | CallExpr | test.rs:4:12:6:5 | BlockExpr | semmle.order | 1 |
61+
| test.rs:5:19:5:19 | LiteralExpr | test.rs:5:9:5:20 | CallExpr | semmle.label | |
62+
| test.rs:5:19:5:19 | LiteralExpr | test.rs:5:9:5:20 | CallExpr | semmle.order | 1 |
63+
| test.rs:9:1:16:1 | decrement | test.rs:9:1:16:1 | exit decrement (normal) | semmle.label | |
64+
| test.rs:9:1:16:1 | decrement | test.rs:9:1:16:1 | exit decrement (normal) | semmle.order | 1 |
65+
| test.rs:9:1:16:1 | enter decrement | test.rs:11:8:11:8 | PathExpr | semmle.label | |
66+
| test.rs:9:1:16:1 | enter decrement | test.rs:11:8:11:8 | PathExpr | semmle.order | 1 |
67+
| test.rs:9:1:16:1 | exit decrement (normal) | test.rs:9:1:16:1 | exit decrement | semmle.label | |
68+
| test.rs:9:1:16:1 | exit decrement (normal) | test.rs:9:1:16:1 | exit decrement | semmle.order | 1 |
69+
| test.rs:9:29:16:1 | BlockExpr | test.rs:9:1:16:1 | decrement | semmle.label | |
70+
| test.rs:9:29:16:1 | BlockExpr | test.rs:9:1:16:1 | decrement | semmle.order | 1 |
71+
| test.rs:11:5:15:5 | IfExpr | test.rs:9:29:16:1 | BlockExpr | semmle.label | |
72+
| test.rs:11:5:15:5 | IfExpr | test.rs:9:29:16:1 | BlockExpr | semmle.order | 1 |
73+
| test.rs:11:8:11:8 | PathExpr | test.rs:11:13:11:13 | LiteralExpr | semmle.label | |
74+
| test.rs:11:8:11:8 | PathExpr | test.rs:11:13:11:13 | LiteralExpr | semmle.order | 1 |
75+
| test.rs:11:8:11:13 | BinaryOpExpr | test.rs:12:9:12:9 | LiteralExpr | semmle.label | true |
76+
| test.rs:11:8:11:13 | BinaryOpExpr | test.rs:12:9:12:9 | LiteralExpr | semmle.order | 1 |
77+
| test.rs:11:8:11:13 | BinaryOpExpr | test.rs:14:9:14:9 | PathExpr | semmle.label | false |
78+
| test.rs:11:8:11:13 | BinaryOpExpr | test.rs:14:9:14:9 | PathExpr | semmle.order | 2 |
79+
| test.rs:11:13:11:13 | LiteralExpr | test.rs:11:8:11:13 | BinaryOpExpr | semmle.label | |
80+
| test.rs:11:13:11:13 | LiteralExpr | test.rs:11:8:11:13 | BinaryOpExpr | semmle.order | 1 |
81+
| test.rs:11:15:13:5 | BlockExpr | test.rs:11:5:15:5 | IfExpr | semmle.label | |
82+
| test.rs:11:15:13:5 | BlockExpr | test.rs:11:5:15:5 | IfExpr | semmle.order | 1 |
83+
| test.rs:12:9:12:9 | LiteralExpr | test.rs:11:15:13:5 | BlockExpr | semmle.label | |
84+
| test.rs:12:9:12:9 | LiteralExpr | test.rs:11:15:13:5 | BlockExpr | semmle.order | 1 |
85+
| test.rs:13:12:15:5 | BlockExpr | test.rs:11:5:15:5 | IfExpr | semmle.label | |
86+
| test.rs:13:12:15:5 | BlockExpr | test.rs:11:5:15:5 | IfExpr | semmle.order | 1 |
87+
| test.rs:14:9:14:9 | PathExpr | test.rs:14:13:14:13 | LiteralExpr | semmle.label | |
88+
| test.rs:14:9:14:9 | PathExpr | test.rs:14:13:14:13 | LiteralExpr | semmle.order | 1 |
89+
| test.rs:14:9:14:13 | BinaryOpExpr | test.rs:13:12:15:5 | BlockExpr | semmle.label | |
90+
| test.rs:14:9:14:13 | BinaryOpExpr | test.rs:13:12:15:5 | BlockExpr | semmle.order | 1 |
91+
| test.rs:14:13:14:13 | LiteralExpr | test.rs:14:9:14:13 | BinaryOpExpr | semmle.label | |
92+
| test.rs:14:13:14:13 | LiteralExpr | test.rs:14:9:14:13 | BinaryOpExpr | semmle.order | 1 |

rust/ql/test/library-tests/controlflow/Cfg.ql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44

55
import rust
66
import codeql.rust.controlflow.ControlFlowGraph
7+
import TestUtils
78

89
class MyRelevantNode extends CfgNode {
10+
MyRelevantNode() { toBeTested(this.getScope()) }
11+
912
string getOrderDisambiguation() { result = "" }
1013
}
1114

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
1-
fn main() {
1+
fn main() -> i64 {
22
if "foo" == "bar" {
3-
println!("foobar");
3+
decrement(0)
44
} else {
5-
println!("baz")
5+
decrement(5)
6+
}
7+
}
8+
9+
fn decrement(n: i64) -> i64 {
10+
12;
11+
if n == 0 {
12+
0
13+
} else {
14+
n - 1
615
}
716
}

0 commit comments

Comments
 (0)