Rust: Support loop in CFG

This commit is contained in:
Simon Friis Vindum
2024-09-12 09:29:19 +02:00
parent 076dd07cdc
commit 67a06cb772
3 changed files with 129 additions and 45 deletions

View File

@@ -117,10 +117,39 @@ class IfExprTree extends PostOrderTree instanceof IfExpr {
}
}
class ExprStmtTree extends StandardPostOrderTree instanceof ExprStmt {
override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class LetExprTree extends StandardPostOrderTree instanceof LetExpr {
override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() }
}
class LetStmtTree extends StandardPostOrderTree instanceof LetStmt {
override ControlFlowTree getChildNode(int i) {
// TODO: For now we ignore the else branch (`super.getElse`). This branch
// is guaranteed to be diverging so will need special treatment in the CFG.
i = 0 and result = super.getInitializer()
}
}
class LoopExprTree extends PostOrderTree instanceof LoopExpr {
override predicate propagatesAbnormal(AstNode child) { child = super.getBody() }
override predicate first(AstNode node) { first(super.getBody(), node) }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Edge from the last node in the body to the loop itself
last(super.getBody(), pred, c) and
completionIsNormal(c) and
succ = this
or
// Tie the knot with an edge from the loop back to the first node
pred = this and
first(super.getBody(), succ)
}
}
class LiteralExprTree extends LeafTree instanceof LiteralExpr { }
class PathExprTree extends LeafTree instanceof PathExpr { }

View File

@@ -14,21 +14,36 @@ nodes
| 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 |
| test.rs:9:1:14:1 | enter spin | semmle.order | 16 |
| test.rs:9:1:14:1 | exit spin | semmle.order | 17 |
| test.rs:9:1:14:1 | exit spin (normal) | semmle.order | 18 |
| test.rs:9:1:14:1 | spin | semmle.order | 19 |
| test.rs:9:17:14:1 | BlockExpr | semmle.order | 20 |
| test.rs:10:9:10:13 | LetStmt | semmle.order | 21 |
| test.rs:10:17:10:17 | LiteralExpr | semmle.order | 22 |
| test.rs:11:5:13:5 | LoopExpr | semmle.order | 23 |
| test.rs:11:10:13:5 | BlockExpr | semmle.order | 24 |
| test.rs:12:9:12:9 | PathExpr | semmle.order | 25 |
| test.rs:12:9:12:14 | BinaryOpExpr | semmle.order | 26 |
| test.rs:12:9:12:14 | ExprStmt | semmle.order | 27 |
| test.rs:12:14:12:14 | LiteralExpr | semmle.order | 28 |
| test.rs:16:1:23:1 | decrement | semmle.order | 29 |
| test.rs:16:1:23:1 | enter decrement | semmle.order | 30 |
| test.rs:16:1:23:1 | exit decrement | semmle.order | 31 |
| test.rs:16:1:23:1 | exit decrement (normal) | semmle.order | 32 |
| test.rs:16:29:23:1 | BlockExpr | semmle.order | 33 |
| test.rs:17:5:17:6 | ExprStmt | semmle.order | 34 |
| test.rs:17:5:17:6 | LiteralExpr | semmle.order | 35 |
| test.rs:18:5:22:5 | IfExpr | semmle.order | 36 |
| test.rs:18:8:18:8 | PathExpr | semmle.order | 37 |
| test.rs:18:8:18:13 | BinaryOpExpr | semmle.order | 38 |
| test.rs:18:13:18:13 | LiteralExpr | semmle.order | 39 |
| test.rs:18:15:20:5 | BlockExpr | semmle.order | 40 |
| test.rs:19:9:19:9 | LiteralExpr | semmle.order | 41 |
| test.rs:20:12:22:5 | BlockExpr | semmle.order | 42 |
| test.rs:21:9:21:9 | PathExpr | semmle.order | 43 |
| test.rs:21:9:21:13 | BinaryOpExpr | semmle.order | 44 |
| test.rs:21:13:21:13 | LiteralExpr | semmle.order | 45 |
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 |
@@ -60,33 +75,66 @@ edges
| 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 |
| test.rs:9:1:14:1 | enter spin | test.rs:10:17:10:17 | LiteralExpr | semmle.label | |
| test.rs:9:1:14:1 | enter spin | test.rs:10:17:10:17 | LiteralExpr | semmle.order | 1 |
| test.rs:9:1:14:1 | exit spin (normal) | test.rs:9:1:14:1 | exit spin | semmle.label | |
| test.rs:9:1:14:1 | exit spin (normal) | test.rs:9:1:14:1 | exit spin | semmle.order | 1 |
| test.rs:9:1:14:1 | spin | test.rs:9:1:14:1 | exit spin (normal) | semmle.label | |
| test.rs:9:1:14:1 | spin | test.rs:9:1:14:1 | exit spin (normal) | semmle.order | 1 |
| test.rs:9:17:14:1 | BlockExpr | test.rs:9:1:14:1 | spin | semmle.label | |
| test.rs:9:17:14:1 | BlockExpr | test.rs:9:1:14:1 | spin | semmle.order | 1 |
| test.rs:10:9:10:13 | LetStmt | test.rs:12:9:12:9 | PathExpr | semmle.label | |
| test.rs:10:9:10:13 | LetStmt | test.rs:12:9:12:9 | PathExpr | semmle.order | 1 |
| test.rs:10:17:10:17 | LiteralExpr | test.rs:10:9:10:13 | LetStmt | semmle.label | |
| test.rs:10:17:10:17 | LiteralExpr | test.rs:10:9:10:13 | LetStmt | semmle.order | 1 |
| test.rs:11:5:13:5 | LoopExpr | test.rs:9:17:14:1 | BlockExpr | semmle.label | |
| test.rs:11:5:13:5 | LoopExpr | test.rs:9:17:14:1 | BlockExpr | semmle.order | 1 |
| test.rs:11:5:13:5 | LoopExpr | test.rs:12:9:12:9 | PathExpr | semmle.label | , false, return, true |
| test.rs:11:5:13:5 | LoopExpr | test.rs:12:9:12:9 | PathExpr | semmle.order | 2 |
| test.rs:11:5:13:5 | LoopExpr | test.rs:12:9:12:9 | PathExpr | semmle.order | 3 |
| test.rs:11:5:13:5 | LoopExpr | test.rs:12:9:12:9 | PathExpr | semmle.order | 4 |
| test.rs:11:5:13:5 | LoopExpr | test.rs:12:9:12:9 | PathExpr | semmle.order | 5 |
| test.rs:11:10:13:5 | BlockExpr | test.rs:11:5:13:5 | LoopExpr | semmle.label | |
| test.rs:11:10:13:5 | BlockExpr | test.rs:11:5:13:5 | LoopExpr | semmle.order | 1 |
| test.rs:12:9:12:9 | PathExpr | test.rs:12:14:12:14 | LiteralExpr | semmle.label | |
| test.rs:12:9:12:9 | PathExpr | test.rs:12:14:12:14 | LiteralExpr | semmle.order | 1 |
| test.rs:12:9:12:14 | BinaryOpExpr | test.rs:12:9:12:14 | ExprStmt | semmle.label | |
| test.rs:12:9:12:14 | BinaryOpExpr | test.rs:12:9:12:14 | ExprStmt | semmle.order | 1 |
| test.rs:12:9:12:14 | ExprStmt | test.rs:11:10:13:5 | BlockExpr | semmle.label | |
| test.rs:12:9:12:14 | ExprStmt | test.rs:11:10:13:5 | BlockExpr | semmle.order | 1 |
| test.rs:12:14:12:14 | LiteralExpr | test.rs:12:9:12:14 | BinaryOpExpr | semmle.label | |
| test.rs:12:14:12:14 | LiteralExpr | test.rs:12:9:12:14 | BinaryOpExpr | semmle.order | 1 |
| test.rs:16:1:23:1 | decrement | test.rs:16:1:23:1 | exit decrement (normal) | semmle.label | |
| test.rs:16:1:23:1 | decrement | test.rs:16:1:23:1 | exit decrement (normal) | semmle.order | 1 |
| test.rs:16:1:23:1 | enter decrement | test.rs:17:5:17:6 | LiteralExpr | semmle.label | |
| test.rs:16:1:23:1 | enter decrement | test.rs:17:5:17:6 | LiteralExpr | semmle.order | 1 |
| test.rs:16:1:23:1 | exit decrement (normal) | test.rs:16:1:23:1 | exit decrement | semmle.label | |
| test.rs:16:1:23:1 | exit decrement (normal) | test.rs:16:1:23:1 | exit decrement | semmle.order | 1 |
| test.rs:16:29:23:1 | BlockExpr | test.rs:16:1:23:1 | decrement | semmle.label | |
| test.rs:16:29:23:1 | BlockExpr | test.rs:16:1:23:1 | decrement | semmle.order | 1 |
| test.rs:17:5:17:6 | ExprStmt | test.rs:18:8:18:8 | PathExpr | semmle.label | |
| test.rs:17:5:17:6 | ExprStmt | test.rs:18:8:18:8 | PathExpr | semmle.order | 1 |
| test.rs:17:5:17:6 | LiteralExpr | test.rs:17:5:17:6 | ExprStmt | semmle.label | |
| test.rs:17:5:17:6 | LiteralExpr | test.rs:17:5:17:6 | ExprStmt | semmle.order | 1 |
| test.rs:18:5:22:5 | IfExpr | test.rs:16:29:23:1 | BlockExpr | semmle.label | |
| test.rs:18:5:22:5 | IfExpr | test.rs:16:29:23:1 | BlockExpr | semmle.order | 1 |
| test.rs:18:8:18:8 | PathExpr | test.rs:18:13:18:13 | LiteralExpr | semmle.label | |
| test.rs:18:8:18:8 | PathExpr | test.rs:18:13:18:13 | LiteralExpr | semmle.order | 1 |
| test.rs:18:8:18:13 | BinaryOpExpr | test.rs:19:9:19:9 | LiteralExpr | semmle.label | true |
| test.rs:18:8:18:13 | BinaryOpExpr | test.rs:19:9:19:9 | LiteralExpr | semmle.order | 1 |
| test.rs:18:8:18:13 | BinaryOpExpr | test.rs:21:9:21:9 | PathExpr | semmle.label | false |
| test.rs:18:8:18:13 | BinaryOpExpr | test.rs:21:9:21:9 | PathExpr | semmle.order | 2 |
| test.rs:18:13:18:13 | LiteralExpr | test.rs:18:8:18:13 | BinaryOpExpr | semmle.label | |
| test.rs:18:13:18:13 | LiteralExpr | test.rs:18:8:18:13 | BinaryOpExpr | semmle.order | 1 |
| test.rs:18:15:20:5 | BlockExpr | test.rs:18:5:22:5 | IfExpr | semmle.label | |
| test.rs:18:15:20:5 | BlockExpr | test.rs:18:5:22:5 | IfExpr | semmle.order | 1 |
| test.rs:19:9:19:9 | LiteralExpr | test.rs:18:15:20:5 | BlockExpr | semmle.label | |
| test.rs:19:9:19:9 | LiteralExpr | test.rs:18:15:20:5 | BlockExpr | semmle.order | 1 |
| test.rs:20:12:22:5 | BlockExpr | test.rs:18:5:22:5 | IfExpr | semmle.label | |
| test.rs:20:12:22:5 | BlockExpr | test.rs:18:5:22:5 | IfExpr | semmle.order | 1 |
| test.rs:21:9:21:9 | PathExpr | test.rs:21:13:21:13 | LiteralExpr | semmle.label | |
| test.rs:21:9:21:9 | PathExpr | test.rs:21:13:21:13 | LiteralExpr | semmle.order | 1 |
| test.rs:21:9:21:13 | BinaryOpExpr | test.rs:20:12:22:5 | BlockExpr | semmle.label | |
| test.rs:21:9:21:13 | BinaryOpExpr | test.rs:20:12:22:5 | BlockExpr | semmle.order | 1 |
| test.rs:21:13:21:13 | LiteralExpr | test.rs:21:9:21:13 | BinaryOpExpr | semmle.label | |
| test.rs:21:13:21:13 | LiteralExpr | test.rs:21:9:21:13 | BinaryOpExpr | semmle.order | 1 |

View File

@@ -6,6 +6,13 @@ fn main() -> i64 {
}
}
fn spin(n: i64) {
let mut i = 0;
loop {
i += 1;
}
}
fn decrement(n: i64) -> i64 {
12;
if n == 0 {