Skip to content

Commit 6d972be

Browse files
committed
Rust: Add a few control flow tree classes
1 parent 91d5171 commit 6d972be

File tree

4 files changed

+64
-6
lines changed

4 files changed

+64
-6
lines changed

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
private import rust
1+
private import codeql.util.Boolean
22
private import codeql.rust.controlflow.ControlFlowGraph
3+
private import rust
34
private import SuccessorType
45
private import SuccessorTypes
56

67
private newtype TCompletion =
78
TSimpleCompletion() or
8-
TBooleanCompletion(boolean b) { b in [false, true] } or
9+
TBooleanCompletion(Boolean b) or
910
TReturnCompletion()
1011

1112
/** A completion of a statement or an expression. */
@@ -82,3 +83,12 @@ class ReturnCompletion extends TReturnCompletion, Completion {
8283

8384
override string toString() { result = "return" }
8485
}
86+
87+
/** Hold if `c` represents normal evaluation of a statement or an expression. */
88+
predicate completionIsNormal(Completion c) { c instanceof NormalCompletion }
89+
90+
/** Hold if `c` represents simple and normal evaluation of a statement or an expression. */
91+
predicate completionIsSimple(Completion c) { c instanceof SimpleCompletion }
92+
93+
/** Holds if `c` is a valid completion for `n`. */
94+
predicate completionIsValidFor(Completion c, AstNode n) { c.isValidFor(n) }
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,47 @@
1+
private import rust
12
import ControlFlowGraphImplSpecific::CfgImpl
3+
import Completion
4+
5+
class CallTree extends StandardPostOrderTree instanceof Call {
6+
override ControlFlowTree getChildNode(int i) { result = super.getArg(i) }
7+
}
8+
9+
class BinaryOpTree extends StandardPostOrderTree instanceof BinaryOp {
10+
override ControlFlowTree getChildNode(int i) {
11+
i = 0 and result = super.getLhs()
12+
or
13+
i = 1 and result = super.getRhs()
14+
}
15+
}
16+
17+
class IfTree extends PostOrderTree instanceof If {
18+
override predicate first(AstNode node) { first(super.getCondition(), node) }
19+
20+
override predicate propagatesAbnormal(AstNode child) { none() }
21+
22+
override predicate succ(AstNode pred, AstNode succ, Completion c) {
23+
// Edges from the condition to each branch
24+
last(super.getCondition(), pred, c) and
25+
(
26+
first(super.getThen(), succ) and c.(BooleanCompletion).getValue() = true
27+
or
28+
first(super.getElse(), succ) and c.(BooleanCompletion).getValue() = false
29+
)
30+
or
31+
// An edge from the then branch to the last node
32+
last(super.getThen(), pred, c) and
33+
succ = this and
34+
completionIsSimple(c)
35+
or
36+
// An edge from the else branch to the last node
37+
last(super.getElse(), pred, c) and
38+
succ = this and
39+
completionIsSimple(c)
40+
}
41+
}
42+
43+
class LetTree extends StandardPostOrderTree instanceof Let {
44+
override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() }
45+
}
46+
47+
class LiteralTree extends LeafTree instanceof Literal { }

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ module CfgInput implements InputSig<Rust::Location> {
1111

1212
class Completion = C::Completion;
1313

14-
predicate completionIsNormal(Completion c) { c instanceof C::NormalCompletion }
14+
predicate completionIsNormal = C::completionIsNormal/1;
1515

16-
predicate completionIsSimple(Completion c) { c instanceof C::SimpleCompletion }
16+
predicate completionIsSimple = C::completionIsSimple/1;
1717

18-
predicate completionIsValidFor(Completion c, AstNode e) { c.isValidFor(e) }
18+
predicate completionIsValidFor = C::completionIsValidFor/2;
1919

2020
/** An AST node with an associated control-flow graph. */
2121
class CfgScope = Scope::CfgScope;

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
private import codeql.util.Boolean
2+
13
cached
24
newtype TSuccessorType =
35
TSuccessorSuccessor() or
4-
TBooleanSuccessor(boolean b) { b in [false, true] } or
6+
TBooleanSuccessor(Boolean b) or
57
TReturnSuccessor()
68

79
/** The type of a control flow successor. */

0 commit comments

Comments
 (0)