Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5306d1e

Browse files
committed
C#: Move PreBasicBlocks module into own file
1 parent 83fb328 commit 5306d1e

4 files changed

Lines changed: 127 additions & 124 deletions

File tree

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

Lines changed: 11 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ module ControlFlow {
818818
* serve as their own entry-points, thus executing in some version of AST
819819
* pre-order.
820820
*/
821-
private module Successor {
821+
module Successor {
822822
private import semmle.code.csharp.ExprOrStmtParent
823823
private import semmle.code.csharp.controlflow.internal.NonReturning
824824

@@ -2264,119 +2264,6 @@ module ControlFlow {
22642264
}
22652265
import Successor
22662266

2267-
/**
2268-
* Provides a basic block implementation on control flow elements. That is,
2269-
* a "pre-CFG" where the nodes are (unsplit) control flow elements and the
2270-
* successor releation is `succ = succ(pred, _)`.
2271-
*
2272-
* The logic is duplicated from the implementation in `BasicBlocks.qll`, and
2273-
* being an internal class, all predicate documentation has been removed.
2274-
*/
2275-
module PreBasicBlocks {
2276-
private predicate startsBB(ControlFlowElement cfe) {
2277-
not cfe = succ(_, _) and
2278-
(
2279-
exists(succ(cfe, _))
2280-
or
2281-
exists(succExit(cfe, _))
2282-
)
2283-
or
2284-
strictcount(ControlFlowElement pred, Completion c | cfe = succ(pred, c)) > 1
2285-
or
2286-
exists(ControlFlowElement pred, int i |
2287-
cfe = succ(pred, _) and
2288-
i = count(ControlFlowElement succ, Completion c | succ = succ(pred, c))
2289-
|
2290-
i > 1
2291-
or
2292-
i = 1 and
2293-
exists(succExit(pred, _))
2294-
)
2295-
}
2296-
2297-
private predicate intraBBSucc(ControlFlowElement pred, ControlFlowElement succ) {
2298-
succ = succ(pred, _) and
2299-
not startsBB(succ)
2300-
}
2301-
2302-
private predicate bbIndex(ControlFlowElement bbStart, ControlFlowElement cfe, int i) =
2303-
shortestDistances(startsBB/1, intraBBSucc/2)(bbStart, cfe, i)
2304-
2305-
private predicate succBB(PreBasicBlock pred, PreBasicBlock succ) {
2306-
succ = pred.getASuccessor()
2307-
}
2308-
2309-
private predicate entryBB(PreBasicBlock bb) { bb = succEntry(_) }
2310-
2311-
private predicate bbIDominates(PreBasicBlock dom, PreBasicBlock bb) =
2312-
idominance(entryBB/1, succBB/2)(_, dom, bb)
2313-
2314-
class PreBasicBlock extends ControlFlowElement {
2315-
PreBasicBlock() { startsBB(this) }
2316-
2317-
PreBasicBlock getASuccessorByType(SuccessorType t) {
2318-
result = succ(this.getLastElement(), any(Completion c | t.matchesCompletion(c)))
2319-
}
2320-
2321-
PreBasicBlock getASuccessor() { result = this.getASuccessorByType(_) }
2322-
2323-
PreBasicBlock getAPredecessor() { result.getASuccessor() = this }
2324-
2325-
ControlFlowElement getElement(int pos) { bbIndex(this, result, pos) }
2326-
2327-
ControlFlowElement getAnElement() { result = this.getElement(_) }
2328-
2329-
ControlFlowElement getFirstElement() { result = this }
2330-
2331-
ControlFlowElement getLastElement() { result = this.getElement(length() - 1) }
2332-
2333-
int length() { result = strictcount(getAnElement()) }
2334-
2335-
predicate immediatelyDominates(PreBasicBlock bb) { bbIDominates(this, bb) }
2336-
2337-
predicate strictlyDominates(PreBasicBlock bb) { this.immediatelyDominates+(bb) }
2338-
2339-
predicate dominates(PreBasicBlock bb) {
2340-
bb = this
2341-
or
2342-
this.strictlyDominates(bb)
2343-
}
2344-
2345-
predicate inDominanceFrontier(PreBasicBlock df) {
2346-
this.dominatesPredecessor(df) and
2347-
not this.strictlyDominates(df)
2348-
}
2349-
2350-
private predicate dominatesPredecessor(PreBasicBlock df) {
2351-
this.dominates(df.getAPredecessor())
2352-
}
2353-
}
2354-
2355-
class ConditionBlock extends PreBasicBlock {
2356-
ConditionBlock() {
2357-
strictcount(ConditionalCompletion c |
2358-
exists(succ(this.getLastElement(), c))
2359-
or
2360-
exists(succExit(this.getLastElement(), c))
2361-
) > 1
2362-
}
2363-
2364-
private predicate immediatelyControls(PreBasicBlock succ, ConditionalCompletion c) {
2365-
succ = succ(this.getLastElement(), c) and
2366-
forall(PreBasicBlock pred | pred = succ.getAPredecessor() and pred != this |
2367-
succ.dominates(pred)
2368-
)
2369-
}
2370-
2371-
predicate controls(PreBasicBlock controlled, ConditionalSuccessor s) {
2372-
exists(PreBasicBlock succ, ConditionalCompletion c | immediatelyControls(succ, c) |
2373-
succ.dominates(controlled) and
2374-
s.matchesCompletion(c)
2375-
)
2376-
}
2377-
}
2378-
}
2379-
23802267
/**
23812268
* Provides an SSA implementation based on "pre-basic-blocks", restricted
23822269
* to local scope variables and fields/properties that behave like local
@@ -2386,8 +2273,8 @@ module ControlFlow {
23862273
* being an internal class, all predicate documentation has been removed.
23872274
*/
23882275
module PreSsa {
2389-
private import PreBasicBlocks
23902276
private import AssignableDefinitions
2277+
private import semmle.code.csharp.controlflow.internal.PreBasicBlocks
23912278

23922279
/**
23932280
* A simple assignable. Either a local scope variable or a field/property
@@ -2489,7 +2376,7 @@ module ControlFlow {
24892376
}
24902377

24912378
private predicate assignableDefAt(
2492-
PreBasicBlocks::PreBasicBlock bb, int i, AssignableDefinition def, SimpleAssignable a
2379+
PreBasicBlock bb, int i, AssignableDefinition def, SimpleAssignable a
24932380
) {
24942381
bb.getElement(i) = def.getExpr() and
24952382
a = def.getTarget() and
@@ -2569,7 +2456,7 @@ module ControlFlow {
25692456
}
25702457

25712458
predicate assignableDefAtLive(
2572-
PreBasicBlocks::PreBasicBlock bb, int i, AssignableDefinition def, SimpleAssignable a
2459+
PreBasicBlock bb, int i, AssignableDefinition def, SimpleAssignable a
25732460
) {
25742461
assignableDefAt(bb, i, def, a) and
25752462
exists(int rnk | rnk = refRank(bb, i, a, Write(_)) |
@@ -3186,8 +3073,8 @@ module ControlFlow {
31863073
}
31873074

31883075
module BooleanSplitting {
3189-
private import PreBasicBlocks
31903076
private import PreSsa
3077+
private import semmle.code.csharp.controlflow.internal.PreBasicBlocks
31913078

31923079
/** A sub-classification of Boolean splits. */
31933080
abstract class BooleanSplitSubKind extends TBooleanSplitSubKind {
@@ -3859,30 +3746,31 @@ module ControlFlow {
38593746
cached
38603747
private module Cached {
38613748
private import semmle.code.csharp.controlflow.Guards as Guards
3749+
private import semmle.code.csharp.controlflow.internal.PreBasicBlocks
38623750

38633751
pragma[noinline]
38643752
private predicate phiNodeMaybeLive(
3865-
PreBasicBlocks::PreBasicBlock bb, PreSsa::SimpleAssignable a
3753+
PreBasicBlock bb, PreSsa::SimpleAssignable a
38663754
) {
3867-
exists(PreBasicBlocks::PreBasicBlock def | PreSsa::defAt(def, _, _, a) |
3755+
exists(PreBasicBlock def | PreSsa::defAt(def, _, _, a) |
38683756
def.inDominanceFrontier(bb)
38693757
)
38703758
}
38713759

38723760
cached
38733761
newtype TPreSsaDef =
38743762
TExplicitPreSsaDef(
3875-
PreBasicBlocks::PreBasicBlock bb, int i, AssignableDefinition def,
3763+
PreBasicBlock bb, int i, AssignableDefinition def,
38763764
PreSsa::SimpleAssignable a
38773765
) {
38783766
Guards::Internal::CachedWithCFG::forceCachingInSameStage() and
38793767
PreSsa::assignableDefAtLive(bb, i, def, a)
38803768
} or
3881-
TImplicitEntryPreSsaDef(Callable c, PreBasicBlocks::PreBasicBlock bb, Assignable a) {
3769+
TImplicitEntryPreSsaDef(Callable c, PreBasicBlock bb, Assignable a) {
38823770
PreSsa::implicitEntryDef(c, bb, a) and
38833771
PreSsa::liveAtEntry(bb, a)
38843772
} or
3885-
TPhiPreSsaDef(PreBasicBlocks::PreBasicBlock bb, PreSsa::SimpleAssignable a) {
3773+
TPhiPreSsaDef(PreBasicBlock bb, PreSsa::SimpleAssignable a) {
38863774
phiNodeMaybeLive(bb, a) and
38873775
PreSsa::liveAtEntry(bb, a)
38883776
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@ class NullGuardedDataFlowNode extends GuardedDataFlowNode {
628628
/** INTERNAL: Do not use. */
629629
module Internal {
630630
private import ControlFlow::Internal
631+
private import semmle.code.csharp.controlflow.internal.PreBasicBlocks as PreBasicBlocks
631632

632633
newtype TAbstractValue =
633634
TBooleanValue(boolean b) { b = true or b = false } or
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/**
2+
* INTERNAL: Do not use.
3+
*
4+
* Provides a basic block implementation on control flow elements. That is,
5+
* a "pre-CFG" where the nodes are (unsplit) control flow elements and the
6+
* successor releation is `succ = succ(pred, _)`.
7+
*
8+
* The logic is duplicated from the implementation in `BasicBlocks.qll`, and
9+
* being an internal class, all predicate documentation has been removed.
10+
*/
11+
12+
import csharp
13+
private import semmle.code.csharp.controlflow.internal.Completion
14+
private import semmle.code.csharp.controlflow.ControlFlowGraph::ControlFlow
15+
private import Internal::Successor
16+
17+
private predicate startsBB(ControlFlowElement cfe) {
18+
not cfe = succ(_, _) and
19+
(
20+
exists(succ(cfe, _))
21+
or
22+
exists(succExit(cfe, _))
23+
)
24+
or
25+
strictcount(ControlFlowElement pred, Completion c | cfe = succ(pred, c)) > 1
26+
or
27+
exists(ControlFlowElement pred, int i |
28+
cfe = succ(pred, _) and
29+
i = count(ControlFlowElement succ, Completion c | succ = succ(pred, c))
30+
|
31+
i > 1
32+
or
33+
i = 1 and
34+
exists(succExit(pred, _))
35+
)
36+
}
37+
38+
private predicate intraBBSucc(ControlFlowElement pred, ControlFlowElement succ) {
39+
succ = succ(pred, _) and
40+
not startsBB(succ)
41+
}
42+
43+
private predicate bbIndex(ControlFlowElement bbStart, ControlFlowElement cfe, int i) =
44+
shortestDistances(startsBB/1, intraBBSucc/2)(bbStart, cfe, i)
45+
46+
private predicate succBB(PreBasicBlock pred, PreBasicBlock succ) { succ = pred.getASuccessor() }
47+
48+
private predicate entryBB(PreBasicBlock bb) { bb = succEntry(_) }
49+
50+
private predicate bbIDominates(PreBasicBlock dom, PreBasicBlock bb) =
51+
idominance(entryBB/1, succBB/2)(_, dom, bb)
52+
53+
class PreBasicBlock extends ControlFlowElement {
54+
PreBasicBlock() { startsBB(this) }
55+
56+
PreBasicBlock getASuccessorByType(SuccessorType t) {
57+
result = succ(this.getLastElement(), any(Completion c | t.matchesCompletion(c)))
58+
}
59+
60+
PreBasicBlock getASuccessor() { result = this.getASuccessorByType(_) }
61+
62+
PreBasicBlock getAPredecessor() { result.getASuccessor() = this }
63+
64+
ControlFlowElement getElement(int pos) { bbIndex(this, result, pos) }
65+
66+
ControlFlowElement getAnElement() { result = this.getElement(_) }
67+
68+
ControlFlowElement getFirstElement() { result = this }
69+
70+
ControlFlowElement getLastElement() { result = this.getElement(length() - 1) }
71+
72+
int length() { result = strictcount(getAnElement()) }
73+
74+
predicate immediatelyDominates(PreBasicBlock bb) { bbIDominates(this, bb) }
75+
76+
predicate strictlyDominates(PreBasicBlock bb) { this.immediatelyDominates+(bb) }
77+
78+
predicate dominates(PreBasicBlock bb) {
79+
bb = this
80+
or
81+
this.strictlyDominates(bb)
82+
}
83+
84+
predicate inDominanceFrontier(PreBasicBlock df) {
85+
this.dominatesPredecessor(df) and
86+
not this.strictlyDominates(df)
87+
}
88+
89+
private predicate dominatesPredecessor(PreBasicBlock df) { this.dominates(df.getAPredecessor()) }
90+
}
91+
92+
class ConditionBlock extends PreBasicBlock {
93+
ConditionBlock() {
94+
strictcount(ConditionalCompletion c |
95+
exists(succ(this.getLastElement(), c))
96+
or
97+
exists(succExit(this.getLastElement(), c))
98+
) > 1
99+
}
100+
101+
private predicate immediatelyControls(PreBasicBlock succ, ConditionalCompletion c) {
102+
succ = succ(this.getLastElement(), c) and
103+
forall(PreBasicBlock pred | pred = succ.getAPredecessor() and pred != this |
104+
succ.dominates(pred)
105+
)
106+
}
107+
108+
predicate controls(PreBasicBlock controlled, SuccessorTypes::ConditionalSuccessor s) {
109+
exists(PreBasicBlock succ, ConditionalCompletion c | immediatelyControls(succ, c) |
110+
succ.dominates(controlled) and
111+
s.matchesCompletion(c)
112+
)
113+
}
114+
}

csharp/ql/test/library-tests/controlflow/graph/PreBasicBlockConsistency.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import csharp
2-
import ControlFlow::Internal::PreBasicBlocks
2+
import semmle.code.csharp.controlflow.internal.PreBasicBlocks
33

44
predicate bbStartInconsistency(ControlFlowElement cfe) {
55
exists(ControlFlow::BasicBlock bb | bb.getFirstNode() = cfe.getAControlFlowNode()) and

0 commit comments

Comments
 (0)