mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Java: Deprecate redundant basic block predicates.
This commit is contained in:
@@ -10,7 +10,7 @@ private import SemanticExprSpecific::SemanticExprConfig as Specific
|
|||||||
*/
|
*/
|
||||||
class SemBasicBlock extends Specific::BasicBlock {
|
class SemBasicBlock extends Specific::BasicBlock {
|
||||||
/** Holds if this block (transitively) dominates `otherblock`. */
|
/** Holds if this block (transitively) dominates `otherblock`. */
|
||||||
final predicate bbDominates(SemBasicBlock otherBlock) { Specific::bbDominates(this, otherBlock) }
|
final predicate dominates(SemBasicBlock otherBlock) { Specific::bbDominates(this, otherBlock) }
|
||||||
|
|
||||||
/** Gets an expression that is evaluated in this basic block. */
|
/** Gets an expression that is evaluated in this basic block. */
|
||||||
final SemExpr getAnExpr() { result.getBasicBlock() = this }
|
final SemExpr getAnExpr() { result.getBasicBlock() = this }
|
||||||
|
|||||||
@@ -79,23 +79,47 @@ class BasicBlock extends BbImpl::BasicBlock {
|
|||||||
/** Gets the immediately enclosing callable whose body contains this node. */
|
/** Gets the immediately enclosing callable whose body contains this node. */
|
||||||
Callable getEnclosingCallable() { result = this.getScope() }
|
Callable getEnclosingCallable() { result = this.getScope() }
|
||||||
|
|
||||||
/** Gets an immediate successor of this basic block. */
|
/**
|
||||||
BasicBlock getABBSuccessor() { result = this.getASuccessor() }
|
* DEPRECATED: Use `getASuccessor` instead.
|
||||||
|
*
|
||||||
|
* Gets an immediate successor of this basic block.
|
||||||
|
*/
|
||||||
|
deprecated BasicBlock getABBSuccessor() { result = this.getASuccessor() }
|
||||||
|
|
||||||
/** Gets an immediate predecessor of this basic block. */
|
/**
|
||||||
BasicBlock getABBPredecessor() { result.getABBSuccessor() = this }
|
* DEPRECATED: Use `getAPredecessor` instead.
|
||||||
|
*
|
||||||
|
* Gets an immediate predecessor of this basic block.
|
||||||
|
*/
|
||||||
|
deprecated BasicBlock getABBPredecessor() { result.getASuccessor() = this }
|
||||||
|
|
||||||
/** Holds if this basic block strictly dominates `node`. */
|
/**
|
||||||
predicate bbStrictlyDominates(BasicBlock node) { this.strictlyDominates(node) }
|
* DEPRECATED: Use `strictlyDominates` instead.
|
||||||
|
*
|
||||||
|
* Holds if this basic block strictly dominates `node`.
|
||||||
|
*/
|
||||||
|
deprecated predicate bbStrictlyDominates(BasicBlock node) { this.strictlyDominates(node) }
|
||||||
|
|
||||||
/** Holds if this basic block dominates `node`. (This is reflexive.) */
|
/**
|
||||||
predicate bbDominates(BasicBlock node) { this.dominates(node) }
|
* DEPRECATED: Use `dominates` instead.
|
||||||
|
*
|
||||||
|
* Holds if this basic block dominates `node`. (This is reflexive.)
|
||||||
|
*/
|
||||||
|
deprecated predicate bbDominates(BasicBlock node) { this.dominates(node) }
|
||||||
|
|
||||||
/** Holds if this basic block strictly post-dominates `node`. */
|
/**
|
||||||
predicate bbStrictlyPostDominates(BasicBlock node) { this.strictlyPostDominates(node) }
|
* DEPRECATED: Use `strictlyPostDominates` instead.
|
||||||
|
*
|
||||||
|
* Holds if this basic block strictly post-dominates `node`.
|
||||||
|
*/
|
||||||
|
deprecated predicate bbStrictlyPostDominates(BasicBlock node) { this.strictlyPostDominates(node) }
|
||||||
|
|
||||||
/** Holds if this basic block post-dominates `node`. (This is reflexive.) */
|
/**
|
||||||
predicate bbPostDominates(BasicBlock node) { this.postDominates(node) }
|
* DEPRECATED: Use `postDominates` instead.
|
||||||
|
*
|
||||||
|
* Holds if this basic block post-dominates `node`. (This is reflexive.)
|
||||||
|
*/
|
||||||
|
deprecated predicate bbPostDominates(BasicBlock node) { this.postDominates(node) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A basic block that ends in an exit node. */
|
/** A basic block that ends in an exit node. */
|
||||||
|
|||||||
@@ -8,51 +8,72 @@ import java
|
|||||||
* Predicates for basic-block-level dominance.
|
* Predicates for basic-block-level dominance.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** The immediate dominance relation for basic blocks. */
|
/**
|
||||||
predicate bbIDominates(BasicBlock dom, BasicBlock node) { dom.immediatelyDominates(node) }
|
* DEPRECATED: Use `BasicBlock::immediatelyDominates` instead.
|
||||||
|
*
|
||||||
|
* The immediate dominance relation for basic blocks.
|
||||||
|
*/
|
||||||
|
deprecated predicate bbIDominates(BasicBlock dom, BasicBlock node) {
|
||||||
|
dom.immediatelyDominates(node)
|
||||||
|
}
|
||||||
|
|
||||||
/** Exit points for basic-block control-flow. */
|
/** Exit points for basic-block control-flow. */
|
||||||
private predicate bbSink(BasicBlock exit) { exit.getLastNode() instanceof ControlFlow::ExitNode }
|
private predicate bbSink(BasicBlock exit) { exit.getLastNode() instanceof ControlFlow::ExitNode }
|
||||||
|
|
||||||
/** Reversed `bbSucc`. */
|
/** Reversed `bbSucc`. */
|
||||||
private predicate bbPred(BasicBlock post, BasicBlock pre) { post = pre.getABBSuccessor() }
|
private predicate bbPred(BasicBlock post, BasicBlock pre) { post = pre.getASuccessor() }
|
||||||
|
|
||||||
/** The immediate post-dominance relation on basic blocks. */
|
/** The immediate post-dominance relation on basic blocks. */
|
||||||
cached
|
deprecated predicate bbIPostDominates(BasicBlock dominator, BasicBlock node) =
|
||||||
predicate bbIPostDominates(BasicBlock dominator, BasicBlock node) =
|
|
||||||
idominance(bbSink/1, bbPred/2)(_, dominator, node)
|
idominance(bbSink/1, bbPred/2)(_, dominator, node)
|
||||||
|
|
||||||
/** Holds if `dom` strictly dominates `node`. */
|
/**
|
||||||
predicate bbStrictlyDominates(BasicBlock dom, BasicBlock node) { bbIDominates+(dom, node) }
|
* DEPRECATED: Use `BasicBlock::strictlyDominates` instead.
|
||||||
|
*
|
||||||
/** Holds if `dom` dominates `node`. (This is reflexive.) */
|
* Holds if `dom` strictly dominates `node`.
|
||||||
predicate bbDominates(BasicBlock dom, BasicBlock node) {
|
*/
|
||||||
bbStrictlyDominates(dom, node) or dom = node
|
deprecated predicate bbStrictlyDominates(BasicBlock dom, BasicBlock node) {
|
||||||
|
dom.strictlyDominates(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if `dom` strictly post-dominates `node`. */
|
/**
|
||||||
predicate bbStrictlyPostDominates(BasicBlock dom, BasicBlock node) { bbIPostDominates+(dom, node) }
|
* DEPRECATED: Use `BasicBlock::dominates` instead.
|
||||||
|
*
|
||||||
|
* Holds if `dom` dominates `node`. (This is reflexive.)
|
||||||
|
*/
|
||||||
|
deprecated predicate bbDominates(BasicBlock dom, BasicBlock node) { dom.dominates(node) }
|
||||||
|
|
||||||
/** Holds if `dom` post-dominates `node`. (This is reflexive.) */
|
/**
|
||||||
predicate bbPostDominates(BasicBlock dom, BasicBlock node) {
|
* DEPRECATED: Use `BasicBlock::strictlyPostDominates` instead.
|
||||||
bbStrictlyPostDominates(dom, node) or dom = node
|
*
|
||||||
|
* Holds if `dom` strictly post-dominates `node`.
|
||||||
|
*/
|
||||||
|
deprecated predicate bbStrictlyPostDominates(BasicBlock dom, BasicBlock node) {
|
||||||
|
dom.strictlyPostDominates(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEPRECATED: Use `BasicBlock::postDominates` instead.
|
||||||
|
*
|
||||||
|
* Holds if `dom` post-dominates `node`. (This is reflexive.)
|
||||||
|
*/
|
||||||
|
deprecated predicate bbPostDominates(BasicBlock dom, BasicBlock node) { dom.postDominates(node) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The dominance frontier relation for basic blocks.
|
* The dominance frontier relation for basic blocks.
|
||||||
*
|
*
|
||||||
* This is equivalent to:
|
* This is equivalent to:
|
||||||
*
|
*
|
||||||
* ```
|
* ```
|
||||||
* bbDominates(x, w.getABBPredecessor()) and not bbStrictlyDominates(x, w)
|
* x.dominates(w.getAPredecessor()) and not x.strictlyDominates(w)
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
predicate dominanceFrontier(BasicBlock x, BasicBlock w) {
|
predicate dominanceFrontier(BasicBlock x, BasicBlock w) {
|
||||||
x = w.getABBPredecessor() and not bbIDominates(x, w)
|
x = w.getAPredecessor() and not x.immediatelyDominates(w)
|
||||||
or
|
or
|
||||||
exists(BasicBlock prev | dominanceFrontier(prev, w) |
|
exists(BasicBlock prev | dominanceFrontier(prev, w) |
|
||||||
bbIDominates(x, prev) and
|
x.immediatelyDominates(prev) and
|
||||||
not bbIDominates(x, w)
|
not x.immediatelyDominates(w)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +86,7 @@ predicate iDominates(ControlFlowNode dominator, ControlFlowNode node) {
|
|||||||
exists(BasicBlock bb, int i | dominator = bb.getNode(i) and node = bb.getNode(i + 1))
|
exists(BasicBlock bb, int i | dominator = bb.getNode(i) and node = bb.getNode(i + 1))
|
||||||
or
|
or
|
||||||
exists(BasicBlock dom, BasicBlock bb |
|
exists(BasicBlock dom, BasicBlock bb |
|
||||||
bbIDominates(dom, bb) and
|
dom.immediatelyDominates(bb) and
|
||||||
dominator = dom.getLastNode() and
|
dominator = dom.getLastNode() and
|
||||||
node = bb.getFirstNode()
|
node = bb.getFirstNode()
|
||||||
)
|
)
|
||||||
@@ -75,7 +96,7 @@ predicate iDominates(ControlFlowNode dominator, ControlFlowNode node) {
|
|||||||
pragma[inline]
|
pragma[inline]
|
||||||
predicate strictlyDominates(ControlFlowNode dom, ControlFlowNode node) {
|
predicate strictlyDominates(ControlFlowNode dom, ControlFlowNode node) {
|
||||||
// This predicate is gigantic, so it must be inlined.
|
// This predicate is gigantic, so it must be inlined.
|
||||||
bbStrictlyDominates(dom.getBasicBlock(), node.getBasicBlock())
|
dom.getBasicBlock().strictlyDominates(node.getBasicBlock())
|
||||||
or
|
or
|
||||||
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i < j)
|
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i < j)
|
||||||
}
|
}
|
||||||
@@ -84,7 +105,7 @@ predicate strictlyDominates(ControlFlowNode dom, ControlFlowNode node) {
|
|||||||
pragma[inline]
|
pragma[inline]
|
||||||
predicate dominates(ControlFlowNode dom, ControlFlowNode node) {
|
predicate dominates(ControlFlowNode dom, ControlFlowNode node) {
|
||||||
// This predicate is gigantic, so it must be inlined.
|
// This predicate is gigantic, so it must be inlined.
|
||||||
bbStrictlyDominates(dom.getBasicBlock(), node.getBasicBlock())
|
dom.getBasicBlock().strictlyDominates(node.getBasicBlock())
|
||||||
or
|
or
|
||||||
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i <= j)
|
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i <= j)
|
||||||
}
|
}
|
||||||
@@ -93,7 +114,7 @@ predicate dominates(ControlFlowNode dom, ControlFlowNode node) {
|
|||||||
pragma[inline]
|
pragma[inline]
|
||||||
predicate strictlyPostDominates(ControlFlowNode dom, ControlFlowNode node) {
|
predicate strictlyPostDominates(ControlFlowNode dom, ControlFlowNode node) {
|
||||||
// This predicate is gigantic, so it must be inlined.
|
// This predicate is gigantic, so it must be inlined.
|
||||||
bbStrictlyPostDominates(dom.getBasicBlock(), node.getBasicBlock())
|
dom.getBasicBlock().strictlyPostDominates(node.getBasicBlock())
|
||||||
or
|
or
|
||||||
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i > j)
|
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i > j)
|
||||||
}
|
}
|
||||||
@@ -102,7 +123,7 @@ predicate strictlyPostDominates(ControlFlowNode dom, ControlFlowNode node) {
|
|||||||
pragma[inline]
|
pragma[inline]
|
||||||
predicate postDominates(ControlFlowNode dom, ControlFlowNode node) {
|
predicate postDominates(ControlFlowNode dom, ControlFlowNode node) {
|
||||||
// This predicate is gigantic, so it must be inlined.
|
// This predicate is gigantic, so it must be inlined.
|
||||||
bbStrictlyPostDominates(dom.getBasicBlock(), node.getBasicBlock())
|
dom.getBasicBlock().strictlyPostDominates(node.getBasicBlock())
|
||||||
or
|
or
|
||||||
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i >= j)
|
exists(BasicBlock b, int i, int j | dom = b.getNode(i) and node = b.getNode(j) and i >= j)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class ConditionBlock extends BasicBlock {
|
|||||||
exists(BasicBlock succ |
|
exists(BasicBlock succ |
|
||||||
succ = this.getTestSuccessor(testIsTrue) and
|
succ = this.getTestSuccessor(testIsTrue) and
|
||||||
dominatingEdge(this, succ) and
|
dominatingEdge(this, succ) and
|
||||||
succ.bbDominates(controlled)
|
succ.dominates(controlled)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -287,7 +287,7 @@ private predicate switchCaseControls(SwitchCase sc, BasicBlock bb) {
|
|||||||
// Pattern cases are handled as condition blocks
|
// Pattern cases are handled as condition blocks
|
||||||
not sc instanceof PatternCase and
|
not sc instanceof PatternCase and
|
||||||
caseblock.getFirstNode() = sc.getControlFlowNode() and
|
caseblock.getFirstNode() = sc.getControlFlowNode() and
|
||||||
caseblock.bbDominates(bb) and
|
caseblock.dominates(bb) and
|
||||||
// Check we can't fall through from a previous block:
|
// Check we can't fall through from a previous block:
|
||||||
forall(ControlFlowNode pred | pred = sc.getControlFlowNode().getAPredecessor() |
|
forall(ControlFlowNode pred | pred = sc.getControlFlowNode().getAPredecessor() |
|
||||||
isNonFallThroughPredecessor(sc, pred)
|
isNonFallThroughPredecessor(sc, pred)
|
||||||
@@ -307,7 +307,7 @@ private predicate preconditionControls(MethodCall ma, BasicBlock controlled, boo
|
|||||||
exists(BasicBlock check, BasicBlock succ |
|
exists(BasicBlock check, BasicBlock succ |
|
||||||
preconditionBranchEdge(ma, check, succ, branch) and
|
preconditionBranchEdge(ma, check, succ, branch) and
|
||||||
dominatingEdge(check, succ) and
|
dominatingEdge(check, succ) and
|
||||||
succ.bbDominates(controlled)
|
succ.dominates(controlled)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ private predicate callAlwaysPerformsAction(Call call, ActionConfiguration conf)
|
|||||||
private predicate actionDominatesExit(Callable callable, ActionConfiguration conf) {
|
private predicate actionDominatesExit(Callable callable, ActionConfiguration conf) {
|
||||||
exists(ExitBlock exit |
|
exists(ExitBlock exit |
|
||||||
exit.getEnclosingCallable() = callable and
|
exit.getEnclosingCallable() = callable and
|
||||||
actionBlock(conf).bbDominates(exit)
|
actionBlock(conf).dominates(exit)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,12 +56,12 @@ private BasicBlock nonDominatingActionBlock(ActionConfiguration conf) {
|
|||||||
exists(ExitBlock exit |
|
exists(ExitBlock exit |
|
||||||
result = actionBlock(conf) and
|
result = actionBlock(conf) and
|
||||||
exit.getEnclosingCallable() = result.getEnclosingCallable() and
|
exit.getEnclosingCallable() = result.getEnclosingCallable() and
|
||||||
not result.bbDominates(exit)
|
not result.dominates(exit)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class JoinBlock extends BasicBlock {
|
private class JoinBlock extends BasicBlock {
|
||||||
JoinBlock() { 2 <= strictcount(this.getABBPredecessor()) }
|
JoinBlock() { 2 <= strictcount(this.getAPredecessor()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,8 +72,8 @@ private predicate postActionBlock(BasicBlock bb, ActionConfiguration conf) {
|
|||||||
bb = nonDominatingActionBlock(conf)
|
bb = nonDominatingActionBlock(conf)
|
||||||
or
|
or
|
||||||
if bb instanceof JoinBlock
|
if bb instanceof JoinBlock
|
||||||
then forall(BasicBlock pred | pred = bb.getABBPredecessor() | postActionBlock(pred, conf))
|
then forall(BasicBlock pred | pred = bb.getAPredecessor() | postActionBlock(pred, conf))
|
||||||
else postActionBlock(bb.getABBPredecessor(), conf)
|
else postActionBlock(bb.getAPredecessor(), conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if every path through `callable` goes through at least one action node. */
|
/** Holds if every path through `callable` goes through at least one action node. */
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ class UnreachableBasicBlock extends BasicBlock {
|
|||||||
or
|
or
|
||||||
// This block is not reachable in the CFG, and is not the entrypoint in a callable, an
|
// This block is not reachable in the CFG, and is not the entrypoint in a callable, an
|
||||||
// expression in an assert statement, or a catch clause.
|
// expression in an assert statement, or a catch clause.
|
||||||
forall(BasicBlock bb | bb = this.getABBPredecessor() | bb instanceof UnreachableBasicBlock) and
|
forall(BasicBlock bb | bb = this.getAPredecessor() | bb instanceof UnreachableBasicBlock) and
|
||||||
not exists(Callable c | c.getBody().getControlFlowNode() = this.getFirstNode()) and
|
not exists(Callable c | c.getBody().getControlFlowNode() = this.getFirstNode()) and
|
||||||
not this.getFirstNode().asExpr().getEnclosingStmt() instanceof AssertStmt and
|
not this.getFirstNode().asExpr().getEnclosingStmt() instanceof AssertStmt and
|
||||||
not this.getFirstNode().asStmt() instanceof CatchClause
|
not this.getFirstNode().asStmt() instanceof CatchClause
|
||||||
@@ -219,11 +219,10 @@ class UnreachableBasicBlock extends BasicBlock {
|
|||||||
// Not accessible from the switch expression
|
// Not accessible from the switch expression
|
||||||
unreachableCaseBlock = constSwitchStmt.getAFailingCase().getBasicBlock() and
|
unreachableCaseBlock = constSwitchStmt.getAFailingCase().getBasicBlock() and
|
||||||
// Not accessible from the successful case
|
// Not accessible from the successful case
|
||||||
not constSwitchStmt.getMatchingCase().getBasicBlock().getABBSuccessor*() =
|
not constSwitchStmt.getMatchingCase().getBasicBlock().getASuccessor*() = unreachableCaseBlock
|
||||||
unreachableCaseBlock
|
|
||||||
|
|
|
|
||||||
// Blocks dominated by an unreachable case block are unreachable
|
// Blocks dominated by an unreachable case block are unreachable
|
||||||
unreachableCaseBlock.bbDominates(this)
|
unreachableCaseBlock.dominates(this)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ SsaVariable getADefinition(SsaVariable v, boolean fromBackEdge) {
|
|||||||
exists(SsaVariable inp, BasicBlock bb, boolean fbe |
|
exists(SsaVariable inp, BasicBlock bb, boolean fbe |
|
||||||
v.(SsaPhiNode).hasInputFromBlock(inp, bb) and
|
v.(SsaPhiNode).hasInputFromBlock(inp, bb) and
|
||||||
result = getADefinition(inp, fbe) and
|
result = getADefinition(inp, fbe) and
|
||||||
(if v.getBasicBlock().bbDominates(bb) then fromBackEdge = true else fromBackEdge = fbe)
|
(if v.getBasicBlock().dominates(bb) then fromBackEdge = true else fromBackEdge = fbe)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,7 +306,7 @@ private predicate guardControlsPhiBranch(
|
|||||||
guard.directlyControls(upd.getBasicBlock(), branch) and
|
guard.directlyControls(upd.getBasicBlock(), branch) and
|
||||||
upd.getDefiningExpr().(VariableAssign).getSource() = e and
|
upd.getDefiningExpr().(VariableAssign).getSource() = e and
|
||||||
upd = phi.getAPhiInput() and
|
upd = phi.getAPhiInput() and
|
||||||
guard.getBasicBlock().bbStrictlyDominates(phi.getBasicBlock())
|
guard.getBasicBlock().strictlyDominates(phi.getBasicBlock())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -331,7 +331,7 @@ private predicate conditionalAssign(SsaVariable v, Guard guard, boolean branch,
|
|||||||
forall(SsaVariable other | other != upd and other = phi.getAPhiInput() |
|
forall(SsaVariable other | other != upd and other = phi.getAPhiInput() |
|
||||||
guard.directlyControls(other.getBasicBlock(), branch.booleanNot())
|
guard.directlyControls(other.getBasicBlock(), branch.booleanNot())
|
||||||
or
|
or
|
||||||
other.getBasicBlock().bbDominates(guard.getBasicBlock()) and
|
other.getBasicBlock().dominates(guard.getBasicBlock()) and
|
||||||
not other.isLiveAtEndOfBlock(getAGuardBranchSuccessor(guard, branch))
|
not other.isLiveAtEndOfBlock(getAGuardBranchSuccessor(guard, branch))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ private predicate impossibleEdge(BasicBlock bb1, BasicBlock bb2) {
|
|||||||
private predicate leavingFinally(BasicBlock bb1, BasicBlock bb2, boolean normaledge) {
|
private predicate leavingFinally(BasicBlock bb1, BasicBlock bb2, boolean normaledge) {
|
||||||
exists(TryStmt try, BlockStmt finally |
|
exists(TryStmt try, BlockStmt finally |
|
||||||
try.getFinally() = finally and
|
try.getFinally() = finally and
|
||||||
bb1.getABBSuccessor() = bb2 and
|
bb1.getASuccessor() = bb2 and
|
||||||
bb1.getFirstNode().getEnclosingStmt().getEnclosingStmt*() = finally and
|
bb1.getFirstNode().getEnclosingStmt().getEnclosingStmt*() = finally and
|
||||||
not bb2.getFirstNode().getEnclosingStmt().getEnclosingStmt*() = finally and
|
not bb2.getFirstNode().getEnclosingStmt().getEnclosingStmt*() = finally and
|
||||||
if bb1.getLastNode().getANormalSuccessor() = bb2.getFirstNode()
|
if bb1.getLastNode().getANormalSuccessor() = bb2.getFirstNode()
|
||||||
@@ -339,7 +339,7 @@ private predicate nullVarStep(
|
|||||||
midssa.isLiveAtEndOfBlock(mid) and
|
midssa.isLiveAtEndOfBlock(mid) and
|
||||||
not ensureNotNull(midssa).getBasicBlock() = mid and
|
not ensureNotNull(midssa).getBasicBlock() = mid and
|
||||||
not assertFail(mid, _) and
|
not assertFail(mid, _) and
|
||||||
bb = mid.getABBSuccessor() and
|
bb = mid.getASuccessor() and
|
||||||
not impossibleEdge(mid, bb) and
|
not impossibleEdge(mid, bb) and
|
||||||
not exists(boolean branch | nullGuard(midssa, branch, false).hasBranchEdge(mid, bb, branch)) and
|
not exists(boolean branch | nullGuard(midssa, branch, false).hasBranchEdge(mid, bb, branch)) and
|
||||||
not (leavingFinally(mid, bb, true) and midstoredcompletion = true) and
|
not (leavingFinally(mid, bb, true) and midstoredcompletion = true) and
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ module Sem implements Semantic<Location> {
|
|||||||
|
|
||||||
class BasicBlock = J::BasicBlock;
|
class BasicBlock = J::BasicBlock;
|
||||||
|
|
||||||
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getABBSuccessor() }
|
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
|
||||||
|
|
||||||
private predicate id(ExprParent x, ExprParent y) { x = y }
|
private predicate id(ExprParent x, ExprParent y) { x = y }
|
||||||
|
|
||||||
|
|||||||
@@ -321,14 +321,14 @@ private module Input implements TypeFlowInput<Location> {
|
|||||||
*/
|
*/
|
||||||
private predicate instanceofDisjunct(InstanceOfExpr ioe, BasicBlock bb, BaseSsaVariable v) {
|
private predicate instanceofDisjunct(InstanceOfExpr ioe, BasicBlock bb, BaseSsaVariable v) {
|
||||||
ioe.getExpr() = v.getAUse() and
|
ioe.getExpr() = v.getAUse() and
|
||||||
strictcount(bb.getABBPredecessor()) > 1 and
|
strictcount(bb.getAPredecessor()) > 1 and
|
||||||
exists(ConditionBlock cb | cb.getCondition() = ioe and cb.getTestSuccessor(true) = bb)
|
exists(ConditionBlock cb | cb.getCondition() = ioe and cb.getTestSuccessor(true) = bb)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if `bb` is disjunctively guarded by multiple `instanceof` tests on `v`. */
|
/** Holds if `bb` is disjunctively guarded by multiple `instanceof` tests on `v`. */
|
||||||
private predicate instanceofDisjunction(BasicBlock bb, BaseSsaVariable v) {
|
private predicate instanceofDisjunction(BasicBlock bb, BaseSsaVariable v) {
|
||||||
strictcount(InstanceOfExpr ioe | instanceofDisjunct(ioe, bb, v)) =
|
strictcount(InstanceOfExpr ioe | instanceofDisjunct(ioe, bb, v)) =
|
||||||
strictcount(bb.getABBPredecessor())
|
strictcount(bb.getAPredecessor())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -338,7 +338,7 @@ private module Input implements TypeFlowInput<Location> {
|
|||||||
predicate instanceofDisjunctionGuarded(TypeFlowNode n, RefType t) {
|
predicate instanceofDisjunctionGuarded(TypeFlowNode n, RefType t) {
|
||||||
exists(BasicBlock bb, InstanceOfExpr ioe, BaseSsaVariable v, VarAccess va |
|
exists(BasicBlock bb, InstanceOfExpr ioe, BaseSsaVariable v, VarAccess va |
|
||||||
instanceofDisjunction(bb, v) and
|
instanceofDisjunction(bb, v) and
|
||||||
bb.bbDominates(va.getBasicBlock()) and
|
bb.dominates(va.getBasicBlock()) and
|
||||||
va = v.getAUse() and
|
va = v.getAUse() and
|
||||||
instanceofDisjunct(ioe, bb, v) and
|
instanceofDisjunct(ioe, bb, v) and
|
||||||
t = ioe.getSyntacticCheckedType() and
|
t = ioe.getSyntacticCheckedType() and
|
||||||
|
|||||||
@@ -157,15 +157,14 @@ private import BaseSsaImpl
|
|||||||
|
|
||||||
private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||||
private import java as J
|
private import java as J
|
||||||
private import semmle.code.java.controlflow.Dominance as Dom
|
|
||||||
|
|
||||||
class BasicBlock = J::BasicBlock;
|
class BasicBlock = J::BasicBlock;
|
||||||
|
|
||||||
class ControlFlowNode = J::ControlFlowNode;
|
class ControlFlowNode = J::ControlFlowNode;
|
||||||
|
|
||||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { Dom::bbIDominates(result, bb) }
|
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) }
|
||||||
|
|
||||||
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getABBSuccessor() }
|
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
|
||||||
|
|
||||||
class SourceVariable = BaseSsaSourceVariable;
|
class SourceVariable = BaseSsaSourceVariable;
|
||||||
|
|
||||||
|
|||||||
@@ -83,12 +83,12 @@ private module CaptureInput implements VariableCapture::InputSig<Location> {
|
|||||||
|
|
||||||
class ControlFlowNode = J::ControlFlowNode;
|
class ControlFlowNode = J::ControlFlowNode;
|
||||||
|
|
||||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { bbIDominates(result, bb) }
|
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) {
|
||||||
|
result.(J::BasicBlock).immediatelyDominates(bb)
|
||||||
BasicBlock getABasicBlockSuccessor(BasicBlock bb) {
|
|
||||||
result = bb.(J::BasicBlock).getABBSuccessor()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.(J::BasicBlock).getASuccessor() }
|
||||||
|
|
||||||
//TODO: support capture of `this` in lambdas
|
//TODO: support capture of `this` in lambdas
|
||||||
class CapturedVariable instanceof LocalScopeVariable {
|
class CapturedVariable instanceof LocalScopeVariable {
|
||||||
CapturedVariable() {
|
CapturedVariable() {
|
||||||
|
|||||||
@@ -40,14 +40,14 @@ private module ThisFlow {
|
|||||||
|
|
||||||
private int lastRank(BasicBlock b) { result = max(int rankix | thisRank(_, b, rankix)) }
|
private int lastRank(BasicBlock b) { result = max(int rankix | thisRank(_, b, rankix)) }
|
||||||
|
|
||||||
private predicate blockPrecedesThisAccess(BasicBlock b) { thisAccess(_, b.getABBSuccessor*(), _) }
|
private predicate blockPrecedesThisAccess(BasicBlock b) { thisAccess(_, b.getASuccessor*(), _) }
|
||||||
|
|
||||||
private predicate thisAccessBlockReaches(BasicBlock b1, BasicBlock b2) {
|
private predicate thisAccessBlockReaches(BasicBlock b1, BasicBlock b2) {
|
||||||
thisAccess(_, b1, _) and b2 = b1.getABBSuccessor()
|
thisAccess(_, b1, _) and b2 = b1.getASuccessor()
|
||||||
or
|
or
|
||||||
exists(BasicBlock mid |
|
exists(BasicBlock mid |
|
||||||
thisAccessBlockReaches(b1, mid) and
|
thisAccessBlockReaches(b1, mid) and
|
||||||
b2 = mid.getABBSuccessor() and
|
b2 = mid.getASuccessor() and
|
||||||
not thisAccess(_, mid, _) and
|
not thisAccess(_, mid, _) and
|
||||||
blockPrecedesThisAccess(b2)
|
blockPrecedesThisAccess(b2)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -165,15 +165,14 @@ private predicate uncertainVariableUpdate(TrackedVar v, ControlFlowNode n, Basic
|
|||||||
|
|
||||||
private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||||
private import java as J
|
private import java as J
|
||||||
private import semmle.code.java.controlflow.Dominance as Dom
|
|
||||||
|
|
||||||
class BasicBlock = J::BasicBlock;
|
class BasicBlock = J::BasicBlock;
|
||||||
|
|
||||||
class ControlFlowNode = J::ControlFlowNode;
|
class ControlFlowNode = J::ControlFlowNode;
|
||||||
|
|
||||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { Dom::bbIDominates(result, bb) }
|
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) }
|
||||||
|
|
||||||
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getABBSuccessor() }
|
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
|
||||||
|
|
||||||
class SourceVariable = SsaSourceVariable;
|
class SourceVariable = SsaSourceVariable;
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ private class SslProceedCall extends MethodCall {
|
|||||||
/** Holds if `m` trusts all certificates by calling `SslErrorHandler.proceed` unconditionally. */
|
/** Holds if `m` trusts all certificates by calling `SslErrorHandler.proceed` unconditionally. */
|
||||||
predicate trustsAllCerts(OnReceivedSslErrorMethod m) {
|
predicate trustsAllCerts(OnReceivedSslErrorMethod m) {
|
||||||
exists(SslProceedCall pr | pr.getQualifier().(VarAccess).getVariable() = m.handlerArg() |
|
exists(SslProceedCall pr | pr.getQualifier().(VarAccess).getVariable() = m.handlerArg() |
|
||||||
pr.getBasicBlock().bbPostDominates(m.getBody().getBasicBlock())
|
pr.getBasicBlock().postDominates(m.getBody().getBasicBlock())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ private module ValidationMethod<DataFlow::guardChecksSig/3 validationGuard> {
|
|||||||
validationMethod(ma.getMethod(), pos) and
|
validationMethod(ma.getMethod(), pos) and
|
||||||
ma.getArgument(pos) = rv and
|
ma.getArgument(pos) = rv and
|
||||||
adjacentUseUseSameVar(rv, result.asExpr()) and
|
adjacentUseUseSameVar(rv, result.asExpr()) and
|
||||||
ma.getBasicBlock().bbDominates(result.asExpr().getBasicBlock())
|
ma.getBasicBlock().dominates(result.asExpr().getBasicBlock())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ private class FullyDecodesUrlBarrier extends DataFlow::Node {
|
|||||||
exists(Variable v, Expr e | this.asExpr() = v.getAnAccess() |
|
exists(Variable v, Expr e | this.asExpr() = v.getAnAccess() |
|
||||||
fullyDecodesUrlGuard(e) and
|
fullyDecodesUrlGuard(e) and
|
||||||
e = v.getAnAccess() and
|
e = v.getAnAccess() and
|
||||||
e.getBasicBlock().bbDominates(this.asExpr().getBasicBlock())
|
e.getBasicBlock().dominates(this.asExpr().getBasicBlock())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,14 +42,14 @@ private predicate validatedAccess(VarAccess va) {
|
|||||||
exists(BasicBlock succ |
|
exists(BasicBlock succ |
|
||||||
succ.getFirstNode() = node.getANormalSuccessor() and
|
succ.getFirstNode() = node.getANormalSuccessor() and
|
||||||
dominatingEdge(node.getBasicBlock(), succ) and
|
dominatingEdge(node.getBasicBlock(), succ) and
|
||||||
succ.bbDominates(va.getBasicBlock())
|
succ.dominates(va.getBasicBlock())
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(BasicBlock bb, int i |
|
exists(BasicBlock bb, int i |
|
||||||
bb.getNode(i) = node and
|
bb.getNode(i) = node and
|
||||||
bb.getNode(i + 1) = node.getANormalSuccessor()
|
bb.getNode(i + 1) = node.getANormalSuccessor()
|
||||||
|
|
|
|
||||||
bb.bbStrictlyDominates(va.getBasicBlock()) or
|
bb.strictlyDominates(va.getBasicBlock()) or
|
||||||
bb.getNode(any(int j | j > i)).asExpr() = va
|
bb.getNode(any(int j | j > i)).asExpr() = va
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -145,9 +145,7 @@ predicate variableLockStateCheck(LockType t, BasicBlock checkblock, BasicBlock f
|
|||||||
predicate blockIsLocked(LockType t, BasicBlock src, BasicBlock b, int locks) {
|
predicate blockIsLocked(LockType t, BasicBlock src, BasicBlock b, int locks) {
|
||||||
lockUnlockBlock(t, b, locks) and src = b and locks > 0
|
lockUnlockBlock(t, b, locks) and src = b and locks > 0
|
||||||
or
|
or
|
||||||
exists(BasicBlock pred, int predlocks, int curlocks, int failedlock |
|
exists(BasicBlock pred, int predlocks, int curlocks, int failedlock | pred = b.getAPredecessor() |
|
||||||
pred = b.getABBPredecessor()
|
|
||||||
|
|
|
||||||
// The number of net locks from the `src` block to the predecessor block `pred` is `predlocks`.
|
// The number of net locks from the `src` block to the predecessor block `pred` is `predlocks`.
|
||||||
blockIsLocked(t, src, pred, predlocks) and
|
blockIsLocked(t, src, pred, predlocks) and
|
||||||
// The recursive call ensures that at least one lock is held, so do not consider the false
|
// The recursive call ensures that at least one lock is held, so do not consider the false
|
||||||
|
|||||||
@@ -18,6 +18,6 @@ where
|
|||||||
iteration = inner.getAnIterationVariable() and
|
iteration = inner.getAnIterationVariable() and
|
||||||
iteration = outer.getAnIterationVariable() and
|
iteration = outer.getAnIterationVariable() and
|
||||||
inner.getEnclosingStmt+() = outer and
|
inner.getEnclosingStmt+() = outer and
|
||||||
inner.getBasicBlock().getABBSuccessor+() = outer.getCondition().getBasicBlock()
|
inner.getBasicBlock().getASuccessor+() = outer.getCondition().getBasicBlock()
|
||||||
select inner.getCondition(), "Nested for statement uses loop variable $@ of enclosing $@.",
|
select inner.getCondition(), "Nested for statement uses loop variable $@ of enclosing $@.",
|
||||||
iteration, iteration.getName(), outer, "for statement"
|
iteration, iteration.getName(), outer, "for statement"
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ predicate overwritten(VariableUpdate upd) {
|
|||||||
bb1.getNode(i) = upd.getControlFlowNode() and
|
bb1.getNode(i) = upd.getControlFlowNode() and
|
||||||
bb2.getNode(j) = overwrite.getControlFlowNode()
|
bb2.getNode(j) = overwrite.getControlFlowNode()
|
||||||
|
|
|
|
||||||
bb1.getABBSuccessor+() = bb2
|
bb1.getASuccessor+() = bb2
|
||||||
or
|
or
|
||||||
bb1 = bb2 and i < j
|
bb1 = bb2 and i < j
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ private predicate blockInSwitch(SwitchStmt s, BasicBlock b) {
|
|||||||
|
|
||||||
private predicate switchCaseControlFlow(SwitchStmt switch, BasicBlock b1, BasicBlock b2) {
|
private predicate switchCaseControlFlow(SwitchStmt switch, BasicBlock b1, BasicBlock b2) {
|
||||||
blockInSwitch(switch, b1) and
|
blockInSwitch(switch, b1) and
|
||||||
b1.getABBSuccessor() = b2 and
|
b1.getASuccessor() = b2 and
|
||||||
blockInSwitch(switch, b2)
|
blockInSwitch(switch, b2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import semmle.code.java.dataflow.SSA
|
|||||||
|
|
||||||
class SsaConvertibleReadAccess extends VarRead {
|
class SsaConvertibleReadAccess extends VarRead {
|
||||||
SsaConvertibleReadAccess() {
|
SsaConvertibleReadAccess() {
|
||||||
this.getEnclosingCallable().getBody().getBasicBlock().getABBSuccessor*() = this.getBasicBlock() and
|
this.getEnclosingCallable().getBody().getBasicBlock().getASuccessor*() = this.getBasicBlock() and
|
||||||
(
|
(
|
||||||
not exists(this.getQualifier())
|
not exists(this.getQualifier())
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import default
|
import java
|
||||||
import semmle.code.java.controlflow.Dominance
|
import semmle.code.java.controlflow.Dominance
|
||||||
|
|
||||||
from BasicBlock b, BasicBlock b2
|
from BasicBlock b, BasicBlock b2
|
||||||
where bbStrictlyDominates(b, b2)
|
where b.strictlyDominates(b2)
|
||||||
select b, b2
|
select b, b2
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import default
|
import java
|
||||||
|
|
||||||
from BasicBlock b, BasicBlock b2
|
from BasicBlock b, BasicBlock b2
|
||||||
where b.getABBSuccessor() = b2
|
where b.getASuccessor() = b2
|
||||||
select b, b2
|
select b, b2
|
||||||
|
|||||||
@@ -16,6 +16,6 @@ predicate dominanceCounterExample(ControlFlowNode entry, ControlFlowNode dom, Co
|
|||||||
|
|
||||||
from Callable c, ControlFlowNode dom, ControlFlowNode node
|
from Callable c, ControlFlowNode dom, ControlFlowNode node
|
||||||
where
|
where
|
||||||
(strictlyDominates(dom, node) or bbStrictlyDominates(dom, node)) and
|
strictlyDominates(dom, node) and
|
||||||
dominanceCounterExample(c.getBody().getControlFlowNode(), dom, node)
|
dominanceCounterExample(c.getBody().getControlFlowNode(), dom, node)
|
||||||
select c, dom, node
|
select c, dom, node
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import default
|
import java
|
||||||
import semmle.code.java.controlflow.Dominance
|
import semmle.code.java.controlflow.Dominance
|
||||||
|
|
||||||
from BasicBlock b, BasicBlock b2
|
from BasicBlock b, BasicBlock b2
|
||||||
where bbStrictlyDominates(b, b2)
|
where b.strictlyDominates(b2)
|
||||||
select b, b2
|
select b, b2
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import default
|
import java
|
||||||
|
|
||||||
from BasicBlock b, BasicBlock b2
|
from BasicBlock b, BasicBlock b2
|
||||||
where b.getABBSuccessor() = b2
|
where b.getASuccessor() = b2
|
||||||
select b, b2
|
select b, b2
|
||||||
|
|||||||
@@ -16,6 +16,6 @@ predicate dominanceCounterExample(ControlFlowNode entry, ControlFlowNode dom, Co
|
|||||||
|
|
||||||
from Callable c, ControlFlowNode dom, ControlFlowNode node
|
from Callable c, ControlFlowNode dom, ControlFlowNode node
|
||||||
where
|
where
|
||||||
(strictlyDominates(dom, node) or bbStrictlyDominates(dom, node)) and
|
strictlyDominates(dom, node) and
|
||||||
dominanceCounterExample(c.getBody().getControlFlowNode(), dom, node)
|
dominanceCounterExample(c.getBody().getControlFlowNode(), dom, node)
|
||||||
select c, dom, node
|
select c, dom, node
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import default
|
import java
|
||||||
import semmle.code.java.controlflow.Dominance
|
import semmle.code.java.controlflow.Dominance
|
||||||
|
|
||||||
from BasicBlock b, BasicBlock b2
|
from BasicBlock b, BasicBlock b2
|
||||||
where bbStrictlyDominates(b, b2)
|
where b.strictlyDominates(b2)
|
||||||
select b, b2
|
select b, b2
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import default
|
import java
|
||||||
|
|
||||||
from BasicBlock b, BasicBlock b2
|
from BasicBlock b, BasicBlock b2
|
||||||
where b.getABBSuccessor() = b2
|
where b.getASuccessor() = b2
|
||||||
select b, b2
|
select b, b2
|
||||||
|
|||||||
@@ -16,6 +16,6 @@ predicate dominanceCounterExample(ControlFlowNode entry, ControlFlowNode dom, Co
|
|||||||
|
|
||||||
from Callable c, ControlFlowNode dom, ControlFlowNode node
|
from Callable c, ControlFlowNode dom, ControlFlowNode node
|
||||||
where
|
where
|
||||||
(strictlyDominates(dom, node) or bbStrictlyDominates(dom, node)) and
|
strictlyDominates(dom, node) and
|
||||||
dominanceCounterExample(c.getBody().getControlFlowNode(), dom, node)
|
dominanceCounterExample(c.getBody().getControlFlowNode(), dom, node)
|
||||||
select c, dom, node
|
select c, dom, node
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ signature module Semantic<LocationSig Location> {
|
|||||||
|
|
||||||
class BasicBlock {
|
class BasicBlock {
|
||||||
/** Holds if this block (transitively) dominates `otherblock`. */
|
/** Holds if this block (transitively) dominates `otherblock`. */
|
||||||
predicate bbDominates(BasicBlock otherBlock);
|
predicate dominates(BasicBlock otherBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets an immediate successor of basic block `bb`, if any. */
|
/** Gets an immediate successor of basic block `bb`, if any. */
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ module MakeUtils<LocationSig Location, Semantic<Location> Lang, DeltaSig D> {
|
|||||||
predicate backEdge(SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge) {
|
predicate backEdge(SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge) {
|
||||||
edge.phiInput(phi, inp) and
|
edge.phiInput(phi, inp) and
|
||||||
(
|
(
|
||||||
phi.getBasicBlock().bbDominates(edge.getOrigBlock()) or
|
phi.getBasicBlock().dominates(edge.getOrigBlock()) or
|
||||||
irreducibleSccEdge(edge.getOrigBlock(), phi.getBasicBlock())
|
irreducibleSccEdge(edge.getOrigBlock(), phi.getBasicBlock())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -227,7 +227,7 @@ module MakeUtils<LocationSig Location, Semantic<Location> Lang, DeltaSig D> {
|
|||||||
|
|
||||||
private predicate trimmedEdge(BasicBlock pred, BasicBlock succ) {
|
private predicate trimmedEdge(BasicBlock pred, BasicBlock succ) {
|
||||||
getABasicBlockSuccessor(pred) = succ and
|
getABasicBlockSuccessor(pred) = succ and
|
||||||
not succ.bbDominates(pred)
|
not succ.dominates(pred)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user