Skip to content

Commit b69188f

Browse files
committed
C#: Adopt shared CFG construction library from shared controlflow pack
1 parent e011480 commit b69188f

36 files changed

+692
-1863
lines changed

config/identical-files.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -484,10 +484,6 @@
484484
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll",
485485
"swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll"
486486
],
487-
"CFG": [
488-
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll",
489-
"swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll"
490-
],
491487
"TypeTracker": [
492488
"python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll",
493489
"ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll"

csharp/ql/consistency-queries/CfgConsistency.ql

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ import csharp
22
import semmle.code.csharp.controlflow.internal.Completion
33
import semmle.code.csharp.controlflow.internal.PreBasicBlocks
44
import ControlFlow
5-
import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl
5+
import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl::Consistency
66
import semmle.code.csharp.controlflow.internal.Splitting
7-
import Consistency
87

98
private predicate splitBB(ControlFlow::BasicBlock bb) {
109
exists(ControlFlow::Node first |
1110
first = bb.getFirstNode() and
1211
first.isJoin() and
13-
strictcount(first.getAPredecessor().getElement()) = 1
12+
strictcount(first.getAPredecessor().getAstNode()) = 1
1413
)
1514
}
1615

csharp/ql/consistency-queries/DataFlowConsistency.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration {
1010
// TODO: Remove once static initializers are folded into the
1111
// static constructors
1212
exists(ControlFlow::Node cfn |
13-
cfn.getElement() = any(FieldOrProperty f | f.isStatic()).getAChild+() and
13+
cfn.getAstNode() = any(FieldOrProperty f | f.isStatic()).getAChild+() and
1414
cfn = n.getControlFlowNode()
1515
)
1616
}
@@ -19,7 +19,7 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration {
1919
// TODO: Remove once static initializers are folded into the
2020
// static constructors
2121
exists(ControlFlow::Node cfn |
22-
cfn.getElement() = any(FieldOrProperty f | f.isStatic()).getAChild+() and
22+
cfn.getAstNode() = any(FieldOrProperty f | f.isStatic()).getAChild+() and
2323
cfn = call.getControlFlowNode()
2424
)
2525
}

csharp/ql/lib/qlpack.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ extractor: csharp
66
library: true
77
upgrades: upgrades
88
dependencies:
9+
codeql/controlflow: ${workspace}
910
codeql/dataflow: ${workspace}
1011
codeql/mad: ${workspace}
1112
codeql/ssa: ${workspace}

csharp/ql/lib/semmle/code/csharp/commons/Assertions.qll

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
/** Provides classes for assertions. */
22

3-
private import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl
43
private import semmle.code.csharp.frameworks.system.Diagnostics
54
private import semmle.code.csharp.frameworks.system.diagnostics.Contracts
65
private import semmle.code.csharp.frameworks.test.VisualStudio
76
private import semmle.code.csharp.frameworks.System
8-
private import ControlFlow
9-
private import ControlFlow::BasicBlocks
107

118
private newtype TAssertionFailure =
129
TExceptionAssertionFailure(Class c) or

csharp/ql/lib/semmle/code/csharp/controlflow/BasicBlocks.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -400,13 +400,13 @@ class ExitBasicBlock extends BasicBlock {
400400

401401
private module JoinBlockPredecessors {
402402
private import ControlFlow::Nodes
403-
private import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl
403+
private import semmle.code.csharp.controlflow.internal.ControlFlowGraphImpl as Impl
404404

405405
int getId(JoinBlockPredecessor jbp) {
406-
exists(ControlFlowTree::Range_ t | ControlFlowTree::idOf(t, result) |
407-
t = jbp.getFirstNode().getElement()
406+
exists(Impl::AstNode n | result = n.getId() |
407+
n = jbp.getFirstNode().getAstNode()
408408
or
409-
t = jbp.(EntryBasicBlock).getCallable()
409+
n = jbp.(EntryBasicBlock).getCallable()
410410
)
411411
}
412412

csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowElement.qll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ private import ControlFlow
77
private import ControlFlow::BasicBlocks
88
private import SuccessorTypes
99
private import semmle.code.csharp.Caching
10-
private import internal.ControlFlowGraphImpl
10+
private import internal.ControlFlowGraphImpl as Impl
1111

1212
/**
1313
* A program element that can possess control flow. That is, either a statement or
@@ -39,20 +39,20 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
3939
* several `ControlFlow::Node`s, for example to represent the continuation
4040
* flow in a `try/catch/finally` construction.
4141
*/
42-
Nodes::ElementNode getAControlFlowNode() { result.getElement() = this }
42+
Nodes::ElementNode getAControlFlowNode() { result.getAstNode() = this }
4343

4444
/**
4545
* Gets a first control flow node executed within this element.
4646
*/
4747
Nodes::ElementNode getAControlFlowEntryNode() {
48-
result = getAControlFlowEntryNode(this).getAControlFlowNode()
48+
result = Impl::getAControlFlowEntryNode(this).(ControlFlowElement).getAControlFlowNode()
4949
}
5050

5151
/**
5252
* Gets a potential last control flow node executed within this element.
5353
*/
5454
Nodes::ElementNode getAControlFlowExitNode() {
55-
result = getAControlFlowExitNode(this).getAControlFlowNode()
55+
result = Impl::getAControlFlowExitNode(this).(ControlFlowElement).getAControlFlowNode()
5656
}
5757

5858
/**
@@ -88,7 +88,7 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
8888
) {
8989
// Only calculate dominance by explicit recursion for split nodes;
9090
// all other nodes can use regular CFG dominance
91-
this instanceof SplitControlFlowElement and
91+
this instanceof Impl::SplitAstNode and
9292
cb.getLastNode() = this.getAControlFlowNode() and
9393
succ = cb.getASuccessorByType(s)
9494
}
@@ -111,7 +111,7 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
111111
succ.dominates(pred)
112112
or
113113
// `pred` might be another split of this element
114-
pred.getLastNode().getElement() = this and
114+
pred.getLastNode().getAstNode() = this and
115115
t = s
116116
)
117117
}

csharp/ql/lib/semmle/code/csharp/controlflow/ControlFlowGraph.qll

Lines changed: 23 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module ControlFlow {
77
private import semmle.code.csharp.controlflow.BasicBlocks as BBs
88
import semmle.code.csharp.controlflow.internal.SuccessorType
99
private import SuccessorTypes
10-
private import internal.ControlFlowGraphImpl
10+
private import internal.ControlFlowGraphImpl as Impl
1111
private import internal.Splitting as Splitting
1212

1313
/**
@@ -25,18 +25,16 @@ module ControlFlow {
2525
* Only nodes that can be reached from the callable entry point are included in
2626
* the CFG.
2727
*/
28-
class Node extends TCfgNode {
29-
/** Gets a textual representation of this control flow node. */
30-
string toString() { none() }
31-
28+
class Node extends Impl::Node {
3229
/** Gets the control flow element that this node corresponds to, if any. */
33-
ControlFlowElement getElement() { none() }
34-
35-
/** Gets the location of this control flow node. */
36-
Location getLocation() { result = this.getElement().getLocation() }
30+
final ControlFlowElement getAstNode() { result = super.getAstNode() }
3731

38-
/** Holds if this control flow node has conditional successors. */
39-
predicate isCondition() { exists(this.getASuccessorByType(any(ConditionalSuccessor e))) }
32+
/**
33+
* DEPRECATED: Use `getAstNode` instead.
34+
*
35+
* Gets the control flow element that this node corresponds to, if any.
36+
*/
37+
deprecated ControlFlowElement getElement() { result = this.getAstNode() }
4038

4139
/** Gets the basic block that this control flow node belongs to. */
4240
BasicBlock getBasicBlock() { result.getANode() = this }
@@ -183,7 +181,7 @@ module ControlFlow {
183181
}
184182

185183
/** Gets a successor node of a given type, if any. */
186-
Node getASuccessorByType(SuccessorType t) { result = getASuccessor(this, t) }
184+
Node getASuccessorByType(SuccessorType t) { result = this.getASuccessor(t) }
187185

188186
/** Gets an immediate successor, if any. */
189187
Node getASuccessor() { result = this.getASuccessorByType(_) }
@@ -234,80 +232,39 @@ module ControlFlow {
234232
result = this.getASuccessorByType(any(BooleanSuccessor t | t.getValue() = false))
235233
}
236234

237-
/** Holds if this node has more than one predecessor. */
238-
predicate isJoin() { strictcount(this.getAPredecessor()) > 1 }
239-
240-
/** Holds if this node has more than one successor. */
241-
predicate isBranch() { strictcount(this.getASuccessor()) > 1 }
242-
243235
/** Gets the enclosing callable of this control flow node. */
244-
final Callable getEnclosingCallable() { result = getNodeCfgScope(this) }
236+
final Callable getEnclosingCallable() { result = Impl::getNodeCfgScope(this) }
245237
}
246238

247239
/** Provides different types of control flow nodes. */
248240
module Nodes {
249241
/** A node for a callable entry point. */
250-
class EntryNode extends Node, TEntryNode {
242+
class EntryNode extends Node instanceof Impl::EntryNode {
251243
/** Gets the callable that this entry applies to. */
252-
Callable getCallable() { this = TEntryNode(result) }
244+
Callable getCallable() { result = this.getScope() }
253245

254246
override BasicBlocks::EntryBlock getBasicBlock() { result = Node.super.getBasicBlock() }
255-
256-
private Assignable getAssignable() { this = TEntryNode(result) }
257-
258-
override Location getLocation() {
259-
result in [this.getCallable().getLocation(), this.getAssignable().getLocation()]
260-
}
261-
262-
override string toString() {
263-
result = "enter " + [this.getCallable().toString(), this.getAssignable().toString()]
264-
}
265247
}
266248

267249
/** A node for a callable exit point, annotated with the type of exit. */
268-
class AnnotatedExitNode extends Node, TAnnotatedExitNode {
269-
private CfgScope scope;
270-
private boolean normal;
271-
272-
AnnotatedExitNode() { this = TAnnotatedExitNode(scope, normal) }
250+
class AnnotatedExitNode extends Node instanceof Impl::AnnotatedExitNode {
251+
/** Holds if this node represent a normal exit. */
252+
final predicate isNormal() { super.isNormal() }
273253

274254
/** Gets the callable that this exit applies to. */
275-
CfgScope getCallable() { result = scope }
276-
277-
/** Holds if this node represents a normal exit. */
278-
predicate isNormal() { normal = true }
255+
Callable getCallable() { result = this.getScope() }
279256

280257
override BasicBlocks::AnnotatedExitBlock getBasicBlock() {
281258
result = Node.super.getBasicBlock()
282259
}
283-
284-
override Location getLocation() { result = scope.getLocation() }
285-
286-
override string toString() {
287-
exists(string s |
288-
normal = true and s = "normal"
289-
or
290-
normal = false and s = "abnormal"
291-
|
292-
result = "exit " + scope + " (" + s + ")"
293-
)
294-
}
295260
}
296261

297262
/** A node for a callable exit point. */
298-
class ExitNode extends Node, TExitNode {
299-
private CfgScope scope;
300-
301-
ExitNode() { this = TExitNode(scope) }
302-
263+
class ExitNode extends Node instanceof Impl::ExitNode {
303264
/** Gets the callable that this exit applies to. */
304-
Callable getCallable() { result = scope }
265+
Callable getCallable() { result = this.getScope() }
305266

306267
override BasicBlocks::ExitBlock getBasicBlock() { result = Node.super.getBasicBlock() }
307-
308-
override Location getLocation() { result = scope.getLocation() }
309-
310-
override string toString() { result = "exit " + scope }
311268
}
312269

313270
/**
@@ -317,35 +274,19 @@ module ControlFlow {
317274
* the element is in unreachable (dead) code, and multiple when there are
318275
* different splits for the element.
319276
*/
320-
class ElementNode extends Node, TElementNode {
321-
private Splits splits;
322-
private ControlFlowElement cfe;
323-
324-
ElementNode() { this = TElementNode(_, cfe, splits) }
325-
326-
override ControlFlowElement getElement() { result = cfe }
327-
328-
override string toString() {
329-
result = "[" + this.getSplitsString() + "] " + cfe.toString()
330-
or
331-
not exists(this.getSplitsString()) and result = cfe.toString()
332-
}
333-
277+
class ElementNode extends Node instanceof Impl::AstCfgNode {
334278
/** Gets a comma-separated list of strings for each split in this node, if any. */
335-
string getSplitsString() {
336-
result = splits.toString() and
337-
result != ""
338-
}
279+
final string getSplitsString() { result = super.getSplitsString() }
339280

340281
/** Gets a split for this control flow node, if any. */
341-
Split getASplit() { result = splits.getASplit() }
282+
final Split getASplit() { result = super.getASplit() }
342283
}
343284

344285
/** A control-flow node for an expression. */
345286
class ExprNode extends ElementNode {
346287
Expr e;
347288

348-
ExprNode() { e = unique(Expr e_ | e_ = this.getElement() | e_) }
289+
ExprNode() { e = unique(Expr e_ | e_ = this.getAstNode() | e_) }
349290

350291
/** Gets the expression that this control-flow node belongs to. */
351292
Expr getExpr() { result = e }

csharp/ql/lib/semmle/code/csharp/controlflow/Guards.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1946,7 +1946,7 @@ module Internal {
19461946
|
19471947
def =
19481948
guarded
1949-
.getElement()
1949+
.getAstNode()
19501950
.(AccessOrCallExpr)
19511951
.getAnSsaQualifier(guarded.getBasicBlock().getANode()) and
19521952
if v.isReferentialProperty()

0 commit comments

Comments
 (0)