Skip to content

Commit 0674881

Browse files
committed
C#: Do not rely on BasicBlock member predicates from SsaImplSpecific
1 parent 2a80601 commit 0674881

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
lines changed

csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
private import SsaImplSpecific
77

8+
private BasicBlock getABasicBlockPredecessor(BasicBlock bb) { getABasicBlockSuccessor(result) = bb }
9+
810
cached
911
private module Cached {
1012
/**
@@ -109,7 +111,7 @@ private module Cached {
109111
* The read that witnesses the liveness of `v` is of kind `rk`.
110112
*/
111113
predicate liveAtExit(BasicBlock bb, SourceVariable v, ReadKind rk) {
112-
liveAtEntry(bb.getASuccessor(), v, rk)
114+
liveAtEntry(getABasicBlockSuccessor(bb), v, rk)
113115
}
114116

115117
/**
@@ -144,6 +146,26 @@ private module Cached {
144146

145147
private import Liveness
146148

149+
/** Holds if `bb1` strictly dominates `bb2`. */
150+
private predicate strictlyDominates(BasicBlock bb1, BasicBlock bb2) {
151+
bb1 = getImmediateBasicBlockDominator+(bb2)
152+
}
153+
154+
/** Holds if `bb1` dominates a predecessor of `bb2`. */
155+
private predicate dominatesPredecessor(BasicBlock bb1, BasicBlock bb2) {
156+
exists(BasicBlock pred | pred = getABasicBlockPredecessor(bb2) |
157+
bb1 = pred
158+
or
159+
strictlyDominates(bb1, pred)
160+
)
161+
}
162+
163+
/** Holds if `df` is in the dominance frontier of `bb`. */
164+
private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) {
165+
dominatesPredecessor(bb, df) and
166+
not strictlyDominates(bb, df)
167+
}
168+
147169
/**
148170
* Holds if `bb` is in the dominance frontier of a block containing a
149171
* definition of `v`.
@@ -152,7 +174,7 @@ private module Cached {
152174
private predicate inDefDominanceFrontier(BasicBlock bb, SourceVariable v) {
153175
exists(BasicBlock defbb, Definition def |
154176
def.definesAt(v, defbb, _) and
155-
defbb.inDominanceFrontier(bb)
177+
inDominanceFrontier(defbb, bb)
156178
)
157179
}
158180

@@ -311,7 +333,7 @@ private module Cached {
311333

312334
pragma[noinline]
313335
private BasicBlock getAMaybeLiveSuccessor(Definition def, BasicBlock bb) {
314-
result = bb.getASuccessor() and
336+
result = getABasicBlockSuccessor(bb) and
315337
not defOccursInBlock(_, bb, def.getSourceVariable()) and
316338
ssaDefReachesEndOfBlock(bb, def, _)
317339
}
@@ -324,7 +346,7 @@ private module Cached {
324346
*/
325347
predicate varBlockReaches(Definition def, BasicBlock bb1, BasicBlock bb2) {
326348
defOccursInBlock(def, bb1, _) and
327-
bb2 = bb1.getASuccessor()
349+
bb2 = getABasicBlockSuccessor(bb1)
328350
or
329351
exists(BasicBlock mid | varBlockReaches(def, bb1, mid) |
330352
bb2 = getAMaybeLiveSuccessor(def, mid)
@@ -355,7 +377,7 @@ private module Cached {
355377
// the node. If two definitions dominate a node then one must dominate the
356378
// other, so therefore the definition of _closest_ is given by the dominator
357379
// tree. Thus, reaching definitions can be calculated in terms of dominance.
358-
idom = getImmediateDominator(bb)
380+
idom = getImmediateBasicBlockDominator(bb)
359381
)
360382
}
361383

@@ -386,7 +408,7 @@ private module Cached {
386408
ssaDefReachesReadWithinBlock(v, def, bb, i, rk)
387409
or
388410
variableRead(bb, i, v, rk) and
389-
ssaDefReachesEndOfBlock(bb.getAPredecessor(), def, v) and
411+
ssaDefReachesEndOfBlock(getABasicBlockPredecessor(bb), def, v) and
390412
not ssaDefReachesReadWithinBlock(v, _, bb, i, _)
391413
}
392414

@@ -402,7 +424,7 @@ private module Cached {
402424
or
403425
exists(BasicBlock bb |
404426
redef.definesAt(v, bb, _) and
405-
ssaDefReachesEndOfBlock(bb.getAPredecessor(), def, v) and
427+
ssaDefReachesEndOfBlock(getABasicBlockPredecessor(bb), def, v) and
406428
not ssaDefReachesUncertainDefWithinBlock(v, _, redef)
407429
)
408430
}
@@ -526,15 +548,15 @@ class PhiNode extends Definition, TPhiNode {
526548
Definition getAnInput() {
527549
exists(BasicBlock bb, BasicBlock pred, SourceVariable v |
528550
this.definesAt(v, bb, _) and
529-
bb.getAPredecessor() = pred and
551+
getABasicBlockPredecessor(bb) = pred and
530552
ssaDefReachesEndOfBlock(pred, result, v)
531553
)
532554
}
533555

534556
/** Holds if `inp` is an input to the phi node along the edge originating in `bb`. */
535557
predicate hasInputFromBlock(Definition inp, BasicBlock bb) {
536558
inp = this.getAnInput() and
537-
this.getBasicBlock().getAPredecessor() = bb and
559+
getABasicBlockPredecessor(this.getBasicBlock()) = bb and
538560
ssaDefReachesEndOfBlock(bb, inp, _)
539561
}
540562

csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplSpecific.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ private import SsaImpl as SsaImpl
66

77
class BasicBlock = ControlFlow::BasicBlock;
88

9-
BasicBlock getImmediateDominator(BasicBlock bb) { result = bb.getImmediateDominator() }
9+
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() }
10+
11+
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
1012

1113
class ExitBasicBlock = ControlFlow::BasicBlocks::ExitBlock;
1214

0 commit comments

Comments
 (0)