Skip to content

Commit 809d040

Browse files
committed
Make more classes private and final
1 parent 6d972be commit 809d040

File tree

10 files changed

+154
-143
lines changed

10 files changed

+154
-143
lines changed

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
private import rust
22
private import ControlFlowGraph
33
private import internal.SuccessorType
4-
private import SuccessorTypes
54
private import internal.ControlFlowGraphImpl as Impl
65
private import codeql.rust.generated.Raw
76
private import codeql.rust.generated.Synth
87

8+
final class BasicBlock = BasicBlockImpl;
9+
910
/**
1011
* A basic block, that is, a maximal straight-line sequence of control flow nodes
1112
* without branches or joins.
1213
*/
13-
class BasicBlock extends TBasicBlockStart {
14+
private class BasicBlockImpl extends TBasicBlockStart {
1415
/** Gets the scope of this basic block. */
1516
CfgScope getScope() { result = this.getAPredecessor().getScope() }
1617

@@ -163,7 +164,7 @@ private predicate entryBB(BasicBlock bb) { bb.getFirstNode() instanceof Impl::En
163164
* An entry basic block, that is, a basic block whose first node is
164165
* an entry node.
165166
*/
166-
class EntryBasicBlock extends BasicBlock {
167+
class EntryBasicBlock extends BasicBlockImpl {
167168
EntryBasicBlock() { entryBB(this) }
168169

169170
override CfgScope getScope() {
@@ -175,7 +176,7 @@ class EntryBasicBlock extends BasicBlock {
175176
* An annotated exit basic block, that is, a basic block whose last node is
176177
* an annotated exit node.
177178
*/
178-
class AnnotatedExitBasicBlock extends BasicBlock {
179+
class AnnotatedExitBasicBlock extends BasicBlockImpl {
179180
private boolean normal;
180181

181182
AnnotatedExitBasicBlock() {
@@ -193,7 +194,7 @@ class AnnotatedExitBasicBlock extends BasicBlock {
193194
* An exit basic block, that is, a basic block whose last node is
194195
* an exit node.
195196
*/
196-
class ExitBasicBlock extends BasicBlock {
197+
class ExitBasicBlock extends BasicBlockImpl {
197198
ExitBasicBlock() { this.getLastNode() instanceof Impl::ExitNode }
198199
}
199200

@@ -220,7 +221,7 @@ private module JoinBlockPredecessors {
220221
}
221222

222223
/** A basic block with more than one predecessor. */
223-
class JoinBlock extends BasicBlock {
224+
class JoinBlock extends BasicBlockImpl {
224225
JoinBlock() { this.getFirstNode().isJoin() }
225226

226227
/**
@@ -231,12 +232,12 @@ class JoinBlock extends BasicBlock {
231232
}
232233

233234
/** A basic block that is an immediate predecessor of a join block. */
234-
class JoinBlockPredecessor extends BasicBlock {
235+
class JoinBlockPredecessor extends BasicBlockImpl {
235236
JoinBlockPredecessor() { this.getASuccessor() instanceof JoinBlock }
236237
}
237238

238239
/** A basic block that terminates in a condition, splitting the subsequent control flow. */
239-
class ConditionBlock extends BasicBlock {
240+
class ConditionBlock extends BasicBlockImpl {
240241
ConditionBlock() { this.getLastNode().isCondition() }
241242

242243
/**

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ private import internal.ControlFlowGraphImpl
55
private import internal.Completion
66
private import internal.SuccessorType
77
private import codeql.rust.controlflow.BasicBlocks
8-
import internal.Scope
8+
private import internal.Scope as Scope
9+
10+
final class CfgScope = Scope::CfgScope;
911

1012
/**
1113
* A control flow node.
@@ -15,21 +17,21 @@ import internal.Scope
1517
*
1618
* Only nodes that can be reached from an entry point are included in the CFG.
1719
*/
18-
class CfgNode extends Node {
20+
final class CfgNode extends Node {
1921
/** Gets the file of this control flow node. */
20-
final File getFile() { result = this.getLocation().getFile() }
22+
File getFile() { result = this.getLocation().getFile() }
2123

2224
/** Gets a successor node of a given type, if any. */
23-
final CfgNode getASuccessor(SuccessorType t) { result = super.getASuccessor(t) }
25+
CfgNode getASuccessor(SuccessorType t) { result = super.getASuccessor(t) }
2426

2527
/** Gets an immediate successor, if any. */
26-
final CfgNode getASuccessor() { result = this.getASuccessor(_) }
28+
CfgNode getASuccessor() { result = this.getASuccessor(_) }
2729

2830
/** Gets an immediate predecessor node of a given flow type, if any. */
29-
final CfgNode getAPredecessor(SuccessorType t) { result.getASuccessor(t) = this }
31+
CfgNode getAPredecessor(SuccessorType t) { result.getASuccessor(t) = this }
3032

3133
/** Gets an immediate predecessor, if any. */
32-
final CfgNode getAPredecessor() { result = this.getAPredecessor(_) }
34+
CfgNode getAPredecessor() { result = this.getAPredecessor(_) }
3335

3436
/** Gets the basic block that this control flow node belongs to. */
3537
BasicBlock getBasicBlock() { result.getANode() = this }

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ private import codeql.util.Boolean
22
private import codeql.rust.controlflow.ControlFlowGraph
33
private import rust
44
private import SuccessorType
5-
private import SuccessorTypes
65

76
private newtype TCompletion =
87
TSimpleCompletion() or
@@ -63,7 +62,7 @@ abstract class ConditionalCompletion extends NormalCompletion {
6362
class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion {
6463
BooleanCompletion() { this = TBooleanCompletion(value) }
6564

66-
override predicate isValidForSpecific(AstNode e) { e = any(If c).getCondition() }
65+
override predicate isValidForSpecific(AstNode e) { e = any(IfExpr c).getCondition() }
6766

6867
/** Gets the dual Boolean completion. */
6968
override BooleanCompletion getDual() { result = TBooleanCompletion(value.booleanNot()) }
@@ -79,7 +78,7 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion {
7978
class ReturnCompletion extends TReturnCompletion, Completion {
8079
override ReturnSuccessor getAMatchingSuccessorType() { any() }
8180

82-
override predicate isValidForSpecific(AstNode e) { e instanceof Return }
81+
override predicate isValidForSpecific(AstNode e) { e instanceof ReturnExpr }
8382

8483
override string toString() { result = "return" }
8584
}
Lines changed: 87 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,101 @@
11
private import rust
2-
import ControlFlowGraphImplSpecific::CfgImpl
2+
import codeql.controlflow.Cfg
33
import Completion
4+
import codeql.controlflow.Cfg
5+
private import SuccessorType as ST
6+
private import Scope as Scope
47

5-
class CallTree extends StandardPostOrderTree instanceof Call {
8+
module CfgInput implements InputSig<Location> {
9+
private import rust as Rust
10+
private import Completion as C
11+
private import Splitting as S
12+
13+
class AstNode = Rust::AstNode;
14+
15+
class Completion = C::Completion;
16+
17+
predicate completionIsNormal = C::completionIsNormal/1;
18+
19+
predicate completionIsSimple = C::completionIsSimple/1;
20+
21+
predicate completionIsValidFor = C::completionIsValidFor/2;
22+
23+
/** An AST node with an associated control-flow graph. */
24+
class CfgScope = Scope::CfgScope;
25+
26+
CfgScope getCfgScope(AstNode n) { result = Scope::scopeOfAst(n) }
27+
28+
class SplitKindBase = S::TSplitKind;
29+
30+
class Split = S::Split;
31+
32+
class SuccessorType = ST::SuccessorType;
33+
34+
/** Gets a successor type that matches completion `c`. */
35+
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
36+
37+
/**
38+
* Hold if `c` represents simple (normal) evaluation of a statement or an expression.
39+
*/
40+
predicate successorTypeIsSimple(SuccessorType t) { t instanceof ST::NormalSuccessor }
41+
42+
/** Holds if `t` is an abnormal exit type out of a CFG scope. */
43+
predicate isAbnormalExitType(SuccessorType t) { none() }
44+
45+
/** Hold if `t` represents a conditional successor type. */
46+
predicate successorTypeIsCondition(SuccessorType t) { t instanceof ST::BooleanSuccessor }
47+
48+
/** Gets the maximum number of splits allowed for a given node. */
49+
int maxSplits() { result = 0 }
50+
51+
/** Holds if `first` is first executed when entering `scope`. */
52+
predicate scopeFirst(CfgScope scope, AstNode first) {
53+
scope.(CfgImpl::ControlFlowTree).first(first)
54+
}
55+
56+
/** Holds if `scope` is exited when `last` finishes with completion `c`. */
57+
predicate scopeLast(CfgScope scope, AstNode last, Completion c) {
58+
scope.(CfgImpl::ControlFlowTree).last(last, c)
59+
}
60+
}
61+
62+
module CfgImpl = Make<Location, CfgInput>;
63+
64+
import CfgImpl
65+
66+
class FunctionTree extends LeafTree instanceof Function { }
67+
68+
class BlockExprTree extends StandardPostOrderTree instanceof BlockExpr {
69+
override ControlFlowTree getChildNode(int i) {
70+
result = super.getStatement(i)
71+
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+
)
78+
}
79+
}
80+
81+
class CallExprTree extends StandardPostOrderTree instanceof CallExpr {
682
override ControlFlowTree getChildNode(int i) { result = super.getArg(i) }
783
}
884

9-
class BinaryOpTree extends StandardPostOrderTree instanceof BinaryOp {
85+
class BinaryOpExprTree extends StandardPostOrderTree instanceof BinaryOpExpr {
1086
override ControlFlowTree getChildNode(int i) {
1187
i = 0 and result = super.getLhs()
1288
or
1389
i = 1 and result = super.getRhs()
1490
}
1591
}
1692

17-
class IfTree extends PostOrderTree instanceof If {
93+
class IfExprTree extends PostOrderTree instanceof IfExpr {
1894
override predicate first(AstNode node) { first(super.getCondition(), node) }
1995

20-
override predicate propagatesAbnormal(AstNode child) { none() }
96+
override predicate propagatesAbnormal(AstNode child) {
97+
child = [super.getCondition(), super.getThen(), super.getElse()]
98+
}
2199

22100
override predicate succ(AstNode pred, AstNode succ, Completion c) {
23101
// Edges from the condition to each branch
@@ -31,17 +109,17 @@ class IfTree extends PostOrderTree instanceof If {
31109
// An edge from the then branch to the last node
32110
last(super.getThen(), pred, c) and
33111
succ = this and
34-
completionIsSimple(c)
112+
completionIsNormal(c)
35113
or
36114
// An edge from the else branch to the last node
37115
last(super.getElse(), pred, c) and
38116
succ = this and
39-
completionIsSimple(c)
117+
completionIsNormal(c)
40118
}
41119
}
42120

43-
class LetTree extends StandardPostOrderTree instanceof Let {
121+
class LetExprTree extends StandardPostOrderTree instanceof LetExpr {
44122
override ControlFlowTree getChildNode(int i) { i = 0 and result = super.getExpr() }
45123
}
46124

47-
class LiteralTree extends LeafTree instanceof Literal { }
125+
class LiteralExprTree extends LeafTree instanceof LiteralExpr { }

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

Lines changed: 0 additions & 63 deletions
This file was deleted.

rust/ql/lib/codeql/rust/controlflow/internal/PrintCFG.ql renamed to rust/ql/lib/codeql/rust/controlflow/internal/PrintCfg.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ external int selectedSourceColumn();
3333

3434
private predicate selectedSourceColumnAlias = selectedSourceColumn/0;
3535

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

3939
predicate selectedSourceLine = selectedSourceLineAlias/0;

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

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,21 @@ abstract class CfgScope extends AstNode { }
66

77
class FunctionScope extends CfgScope, Function { }
88

9-
cached
10-
private module Cached {
11-
/**
12-
* Gets the immediate parent of a non-`AstNode` element `e`.
13-
*
14-
* We restrict `e` to be a non-`AstNode` to skip past non-`AstNode` in
15-
* the transitive closure computation in `getParentOfAst`. This is
16-
* necessary because the parent of an `AstNode` is not necessarily an `AstNode`.
17-
*/
18-
private Element getParentOfAstStep(Element e) {
19-
not e instanceof AstNode and
20-
result = getImmediateParent(e)
21-
}
9+
/**
10+
* Gets the immediate parent of a non-`AstNode` element `e`.
11+
*
12+
* We restrict `e` to be a non-`AstNode` to skip past non-`AstNode` in
13+
* the transitive closure computation in `getParentOfAst`. This is
14+
* necessary because the parent of an `AstNode` is not necessarily an `AstNode`.
15+
*/
16+
private Element getParentOfAstStep(Element e) {
17+
not e instanceof AstNode and
18+
result = getImmediateParent(e)
19+
}
2220

23-
/** Gets the nearest enclosing parent of `ast` that is an `AstNode`. */
24-
cached
25-
AstNode getParentOfAst(AstNode ast) { result = getParentOfAstStep*(getImmediateParent(ast)) }
21+
/** Gets the nearest enclosing parent of `ast` that is an `AstNode`. */
22+
private AstNode getParentOfAst(AstNode ast) {
23+
result = getParentOfAstStep*(getImmediateParent(ast))
2624
}
2725

2826
/** Gets the enclosing scope of a node */
@@ -32,5 +30,3 @@ AstNode scopeOfAst(AstNode n) {
3230
if p instanceof CfgScope then p = result else result = scopeOfAst(p)
3331
)
3432
}
35-
36-
import Cached

0 commit comments

Comments
 (0)