Skip to content

Commit 3d93e01

Browse files
committed
C#: Replace a recursive predicate with doublyBoundedFastTc
1 parent c99ff73 commit 3d93e01

File tree

1 file changed

+36
-5
lines changed

1 file changed

+36
-5
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/internal/ControlFlowReachability.qll

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,47 @@ private class ControlFlowScope extends ControlFlowElement {
1515
predicate isNonExact() { exactScope = false }
1616
}
1717

18-
private ControlFlowElement getANonExactScopeChild(ControlFlowScope scope) {
19-
scope.isNonExact() and
20-
result = scope
18+
private newtype TControlFlowElementOrBasicBlock =
19+
TControlFlowElement(ControlFlowElement cfe) or
20+
TBasicBlock(ControlFlow::BasicBlock bb)
21+
22+
class ControlFlowElementOrBasicBlock extends TControlFlowElementOrBasicBlock {
23+
ControlFlowElement asControlFlowElement() { this = TControlFlowElement(result) }
24+
25+
ControlFlow::BasicBlock asBasicBlock() { this = TBasicBlock(result) }
26+
27+
string toString() {
28+
result = this.asControlFlowElement().toString()
29+
or
30+
result = this.asBasicBlock().toString()
31+
}
32+
33+
Location getLocation() {
34+
result = this.asControlFlowElement().getLocation()
35+
or
36+
result = this.asBasicBlock().getLocation()
37+
}
38+
}
39+
40+
private predicate isBasicBlock(ControlFlowElementOrBasicBlock c) { c instanceof TBasicBlock }
41+
42+
private predicate isNonExactScope(ControlFlowElementOrBasicBlock c) {
43+
c.asControlFlowElement().(ControlFlowScope).isNonExact()
44+
}
45+
46+
private predicate step(ControlFlowElementOrBasicBlock pred, ControlFlowElementOrBasicBlock succ) {
47+
pred.asBasicBlock().getANode().getAstNode() = succ.asControlFlowElement()
2148
or
22-
result = getANonExactScopeChild(scope).getAChild()
49+
pred.asControlFlowElement() = succ.asControlFlowElement().getAChild()
2350
}
2451

52+
private predicate basicBlockInNonExactScope(
53+
ControlFlowElementOrBasicBlock bb, ControlFlowElementOrBasicBlock scope
54+
) = doublyBoundedFastTC(step/2, isBasicBlock/1, isNonExactScope/1)(bb, scope)
55+
2556
pragma[noinline]
2657
private ControlFlow::BasicBlock getABasicBlockInScope(ControlFlowScope scope, boolean exactScope) {
27-
result.getANode().getAstNode() = getANonExactScopeChild(scope) and
58+
basicBlockInNonExactScope(TBasicBlock(result), TControlFlowElement(scope)) and
2859
exactScope = false
2960
or
3061
scope.isExact() and

0 commit comments

Comments
 (0)