Skip to content

Commit 9fad541

Browse files
committed
Rust: implement CFG for macros
1 parent 6d43eed commit 9fad541

File tree

3 files changed

+83
-33
lines changed

3 files changed

+83
-33
lines changed

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

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,7 @@ class BlockExprTree extends StandardPostOrderTree, BlockExpr {
143143
override AstNode getChildNode(int i) {
144144
result = super.getStmtList().getStatement(i)
145145
or
146-
not exists(super.getStmtList().getStatement(i)) and
147-
(exists(super.getStmtList().getStatement(i - 1)) or i = 0) and
146+
i = super.getStmtList().getNumberOfStatements() and
148147
result = super.getStmtList().getTailExpr()
149148
}
150149

@@ -241,6 +240,14 @@ class IfExprTree extends PostOrderTree instanceof IfExpr {
241240
}
242241
}
243242

243+
class FormatArgsExprTree extends StandardPostOrderTree instanceof FormatArgsExpr {
244+
override AstNode getChildNode(int i) {
245+
i = -1 and result = super.getTemplate()
246+
or
247+
result = super.getArg(i).getExpr()
248+
}
249+
}
250+
244251
class IndexExprTree extends StandardPostOrderTree instanceof IndexExpr {
245252
override AstNode getChildNode(int i) {
246253
i = 0 and result = super.getBase()
@@ -249,7 +256,12 @@ class IndexExprTree extends StandardPostOrderTree instanceof IndexExpr {
249256
}
250257
}
251258

252-
class ItemTree extends LeafTree, Item { }
259+
class ItemTree extends LeafTree, Item {
260+
ItemTree() {
261+
not this instanceof MacroCall and
262+
this = [any(StmtList s).getAStatement(), any(MacroStmts s).getAStatement()]
263+
}
264+
}
253265

254266
// `LetExpr` is a pre-order tree such that the pattern itself ends up
255267
// dominating successors in the graph in the same way that patterns do in
@@ -391,8 +403,40 @@ class ForExprTree extends LoopingExprTree instanceof ForExpr {
391403
}
392404
}
393405

394-
// TODO: replace with expanded macro once the extractor supports it
395-
class MacroExprTree extends LeafTree, MacroExpr { }
406+
class MacroCallTree extends ControlFlowTree instanceof MacroCall {
407+
override predicate first(AstNode first) {
408+
first(super.getExpanded(), first)
409+
or
410+
not exists(super.getExpanded()) and first = this
411+
}
412+
413+
override predicate last(AstNode last, Completion c) {
414+
last(super.getExpanded(), last, c)
415+
or
416+
not exists(super.getExpanded()) and last = this
417+
}
418+
419+
override predicate succ(AstNode pred, AstNode succ, Completion c) { none() }
420+
421+
override predicate propagatesAbnormal(AstNode child) { none() }
422+
}
423+
424+
class MacroExprTree extends StandardPostOrderTree instanceof MacroExpr {
425+
override AstNode getChildNode(int i) { i = 0 and result = super.getMacroCall() }
426+
}
427+
428+
class MacroPatTree extends StandardPostOrderTree instanceof MacroExpr {
429+
override AstNode getChildNode(int i) { i = 0 and result = super.getMacroCall() }
430+
}
431+
432+
class MacroStmtsTree extends StandardPreOrderTree instanceof MacroStmts {
433+
override AstNode getChildNode(int i) {
434+
result = super.getStatement(i)
435+
or
436+
i = super.getNumberOfStatements() and
437+
result = super.getExpr()
438+
}
439+
}
396440

397441
class MatchArmTree extends ControlFlowTree instanceof MatchArm {
398442
override predicate propagatesAbnormal(AstNode child) { child = super.getExpr() }

rust/ql/test/library-tests/variables/Cfg.expected

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,30 @@ edges
33
| variables.rs:3:1:5:1 | exit print_str (normal) | variables.rs:3:1:5:1 | exit print_str | |
44
| variables.rs:3:23:5:1 | BlockExpr | variables.rs:3:1:5:1 | exit print_str (normal) | |
55
| variables.rs:4:5:4:21 | MacroExpr | variables.rs:3:23:5:1 | BlockExpr | |
6-
| variables.rs:4:5:4:22 | ExprStmt | variables.rs:4:5:4:21 | MacroExpr | |
6+
| variables.rs:4:5:4:21 | PathExpr | variables.rs:4:14:4:17 | "{}\\n" | |
7+
| variables.rs:4:5:4:22 | ExprStmt | variables.rs:4:14:4:20 | MacroStmts | |
8+
| variables.rs:4:14:4:17 | "{}\\n" | variables.rs:4:20:4:20 | s | |
9+
| variables.rs:4:14:4:20 | BlockExpr | variables.rs:4:5:4:21 | MacroExpr | |
10+
| variables.rs:4:14:4:20 | CallExpr | variables.rs:4:14:4:20 | BlockExpr | |
11+
| variables.rs:4:14:4:20 | ExprStmt | variables.rs:4:5:4:21 | PathExpr | |
12+
| variables.rs:4:14:4:20 | FormatArgsExpr | variables.rs:4:14:4:20 | MacroExpr | |
13+
| variables.rs:4:14:4:20 | MacroExpr | variables.rs:4:14:4:20 | CallExpr | |
14+
| variables.rs:4:14:4:20 | MacroStmts | variables.rs:4:14:4:20 | ExprStmt | |
15+
| variables.rs:4:20:4:20 | s | variables.rs:4:14:4:20 | FormatArgsExpr | |
716
| variables.rs:7:1:9:1 | enter print_i64 | variables.rs:8:5:8:22 | ExprStmt | |
817
| variables.rs:7:1:9:1 | exit print_i64 (normal) | variables.rs:7:1:9:1 | exit print_i64 | |
918
| variables.rs:7:22:9:1 | BlockExpr | variables.rs:7:1:9:1 | exit print_i64 (normal) | |
1019
| variables.rs:8:5:8:21 | MacroExpr | variables.rs:7:22:9:1 | BlockExpr | |
11-
| variables.rs:8:5:8:22 | ExprStmt | variables.rs:8:5:8:21 | MacroExpr | |
20+
| variables.rs:8:5:8:21 | PathExpr | variables.rs:8:14:8:17 | "{}\\n" | |
21+
| variables.rs:8:5:8:22 | ExprStmt | variables.rs:8:14:8:20 | MacroStmts | |
22+
| variables.rs:8:14:8:17 | "{}\\n" | variables.rs:8:20:8:20 | i | |
23+
| variables.rs:8:14:8:20 | BlockExpr | variables.rs:8:5:8:21 | MacroExpr | |
24+
| variables.rs:8:14:8:20 | CallExpr | variables.rs:8:14:8:20 | BlockExpr | |
25+
| variables.rs:8:14:8:20 | ExprStmt | variables.rs:8:5:8:21 | PathExpr | |
26+
| variables.rs:8:14:8:20 | FormatArgsExpr | variables.rs:8:14:8:20 | MacroExpr | |
27+
| variables.rs:8:14:8:20 | MacroExpr | variables.rs:8:14:8:20 | CallExpr | |
28+
| variables.rs:8:14:8:20 | MacroStmts | variables.rs:8:14:8:20 | ExprStmt | |
29+
| variables.rs:8:20:8:20 | i | variables.rs:8:14:8:20 | FormatArgsExpr | |
1230
| variables.rs:11:1:14:1 | enter immutable_variable | variables.rs:12:5:12:17 | LetStmt | |
1331
| variables.rs:11:1:14:1 | exit immutable_variable (normal) | variables.rs:11:1:14:1 | exit immutable_variable | |
1432
| variables.rs:11:25:14:1 | BlockExpr | variables.rs:11:1:14:1 | exit immutable_variable (normal) | |
@@ -149,12 +167,16 @@ edges
149167
| variables.rs:82:1:88:1 | exit let_pattern4 (normal) | variables.rs:82:1:88:1 | exit let_pattern4 | |
150168
| variables.rs:82:19:88:1 | BlockExpr | variables.rs:82:1:88:1 | exit let_pattern4 (normal) | |
151169
| variables.rs:83:5:86:10 | LetStmt | variables.rs:83:34:83:37 | PathExpr | |
152-
| variables.rs:83:9:83:16 | TupleStructPat | variables.rs:85:13:85:19 | MacroExpr | no-match |
170+
| variables.rs:83:9:83:16 | TupleStructPat | variables.rs:85:13:85:19 | MacroStmts | no-match |
153171
| variables.rs:83:9:83:16 | TupleStructPat | variables.rs:87:5:87:18 | ExprStmt | match |
154172
| variables.rs:83:34:83:37 | PathExpr | variables.rs:83:39:83:42 | "x5" | |
155173
| variables.rs:83:34:83:43 | CallExpr | variables.rs:83:9:83:16 | TupleStructPat | |
156174
| variables.rs:83:39:83:42 | "x5" | variables.rs:83:34:83:43 | CallExpr | |
175+
| variables.rs:85:13:85:19 | "not yet implemented" | variables.rs:85:13:85:19 | CallExpr | |
176+
| variables.rs:85:13:85:19 | CallExpr | variables.rs:85:13:85:19 | MacroExpr | |
157177
| variables.rs:85:13:85:19 | MacroExpr | variables.rs:84:14:86:9 | BlockExpr | |
178+
| variables.rs:85:13:85:19 | MacroStmts | variables.rs:85:13:85:19 | PathExpr | |
179+
| variables.rs:85:13:85:19 | PathExpr | variables.rs:85:13:85:19 | "not yet implemented" | |
158180
| variables.rs:87:5:87:13 | PathExpr | variables.rs:87:15:87:16 | x5 | |
159181
| variables.rs:87:5:87:17 | CallExpr | variables.rs:82:19:88:1 | BlockExpr | |
160182
| variables.rs:87:5:87:18 | ExprStmt | variables.rs:87:5:87:13 | PathExpr | |
@@ -279,10 +301,18 @@ edges
279301
| variables.rs:163:14:163:22 | PathExpr | variables.rs:163:24:163:34 | id_variable | |
280302
| variables.rs:163:14:163:35 | CallExpr | variables.rs:160:5:169:5 | MatchExpr | |
281303
| variables.rs:163:24:163:34 | id_variable | variables.rs:163:14:163:35 | CallExpr | |
282-
| variables.rs:164:9:164:38 | RecordPat | variables.rs:165:13:165:52 | MacroExpr | match |
304+
| variables.rs:164:9:164:38 | RecordPat | variables.rs:165:22:165:51 | MacroStmts | match |
283305
| variables.rs:164:9:164:38 | RecordPat | variables.rs:167:9:167:29 | RecordPat | no-match |
284306
| variables.rs:164:43:166:9 | BlockExpr | variables.rs:160:5:169:5 | MatchExpr | |
285307
| variables.rs:165:13:165:52 | MacroExpr | variables.rs:164:43:166:9 | BlockExpr | |
308+
| variables.rs:165:13:165:52 | PathExpr | variables.rs:165:22:165:51 | "Found an id in another range\\n" | |
309+
| variables.rs:165:22:165:51 | "Found an id in another range\\n" | variables.rs:165:22:165:51 | FormatArgsExpr | |
310+
| variables.rs:165:22:165:51 | BlockExpr | variables.rs:165:13:165:52 | MacroExpr | |
311+
| variables.rs:165:22:165:51 | CallExpr | variables.rs:165:22:165:51 | BlockExpr | |
312+
| variables.rs:165:22:165:51 | ExprStmt | variables.rs:165:13:165:52 | PathExpr | |
313+
| variables.rs:165:22:165:51 | FormatArgsExpr | variables.rs:165:22:165:51 | MacroExpr | |
314+
| variables.rs:165:22:165:51 | MacroExpr | variables.rs:165:22:165:51 | CallExpr | |
315+
| variables.rs:165:22:165:51 | MacroStmts | variables.rs:165:22:165:51 | ExprStmt | |
286316
| variables.rs:167:9:167:29 | RecordPat | variables.rs:168:13:168:21 | PathExpr | match |
287317
| variables.rs:168:13:168:21 | PathExpr | variables.rs:168:23:168:24 | id | |
288318
| variables.rs:168:13:168:25 | CallExpr | variables.rs:160:5:169:5 | MatchExpr | |

rust/ql/test/query-tests/unusedentities/UnreachableCode.expected

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,10 @@
1-
| main.rs:14:14:14:24 | ExprStmt | This code is never reached. |
2-
| main.rs:17:18:17:28 | ExprStmt | This code is never reached. |
3-
| main.rs:20:14:20:24 | ExprStmt | This code is never reached. |
4-
| main.rs:21:5:21:19 | ExprStmt | This code is never reached. |
5-
| main.rs:21:5:21:19 | ExprStmt | This code is never reached. |
6-
| main.rs:39:14:39:24 | ExprStmt | This code is never reached. |
7-
| main.rs:48:14:48:24 | ExprStmt | This code is never reached. |
8-
| main.rs:56:14:56:24 | ExprStmt | This code is never reached. |
9-
| main.rs:60:14:60:24 | ExprStmt | This code is never reached. |
10-
| main.rs:68:14:68:24 | ExprStmt | This code is never reached. |
11-
| main.rs:94:14:94:45 | ExprStmt | This code is never reached. |
12-
| main.rs:97:14:97:38 | ExprStmt | This code is never reached. |
13-
| main.rs:99:14:99:38 | ExprStmt | This code is never reached. |
14-
| main.rs:112:14:112:32 | ExprStmt | This code is never reached. |
15-
| main.rs:117:18:117:33 | ExprStmt | This code is never reached. |
16-
| main.rs:171:18:171:29 | ExprStmt | This code is never reached. |
17-
| main.rs:176:9:176:24 | ExprStmt | This code is never reached. |
18-
| main.rs:176:9:176:24 | ExprStmt | This code is never reached. |
19-
| main.rs:332:11:332:51 | ExprStmt | This code is never reached. |
201
| unreachable.rs:12:3:12:17 | ExprStmt | This code is never reached. |
212
| unreachable.rs:20:3:20:17 | ExprStmt | This code is never reached. |
223
| unreachable.rs:32:3:32:17 | ExprStmt | This code is never reached. |
234
| unreachable.rs:39:3:39:17 | ExprStmt | This code is never reached. |
245
| unreachable.rs:60:2:60:16 | ExprStmt | This code is never reached. |
25-
| unreachable.rs:66:10:66:19 | ExprStmt | This code is never reached. |
266
| unreachable.rs:100:16:100:23 | ExprStmt | This code is never reached. |
27-
| unreachable.rs:101:3:101:17 | ExprStmt | This code is never reached. |
28-
| unreachable.rs:102:16:102:23 | ExprStmt | This code is never reached. |
297
| unreachable.rs:108:15:108:22 | ExprStmt | This code is never reached. |
30-
| unreachable.rs:109:3:109:17 | ExprStmt | This code is never reached. |
31-
| unreachable.rs:110:15:110:22 | ExprStmt | This code is never reached. |
328
| unreachable.rs:124:2:124:16 | ExprStmt | This code is never reached. |
339
| unreachable.rs:134:2:134:16 | ExprStmt | This code is never reached. |
3410
| unreachable.rs:141:3:141:17 | ExprStmt | This code is never reached. |

0 commit comments

Comments
 (0)