mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
Merge pull request #2036 from aschackmull/java/eq-ssa-guard
Java: Improve guards for equal ssa variables.
This commit is contained in:
@@ -97,6 +97,16 @@ class Guard extends ExprParent {
|
||||
result = this.(SwitchCase).getSwitchExpr().getEnclosingStmt()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the basic block containing this guard or the basic block containing
|
||||
* the switch expression if the guard is a switch case.
|
||||
*/
|
||||
BasicBlock getBasicBlock() {
|
||||
result = this.(Expr).getBasicBlock() or
|
||||
result = this.(SwitchCase).getSwitch().getExpr().getProperExpr().getBasicBlock() or
|
||||
result = this.(SwitchCase).getSwitchExpr().getExpr().getProperExpr().getBasicBlock()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this guard is an equality test between `e1` and `e2`. The test
|
||||
* can be either `==`, `!=`, `.equals`, or a switch case. If the test is
|
||||
|
||||
@@ -107,7 +107,7 @@ predicate implies_v2(Guard g1, boolean b1, Guard g2, boolean b2) {
|
||||
uniqueValue(v, e, k) and
|
||||
guardImpliesEqual(g1, b1, v, k) and
|
||||
g2.directlyControls(e.getBasicBlock(), b2) and
|
||||
not g2.directlyControls(getBasicBlockOfGuard(g1), b2)
|
||||
not g2.directlyControls(g1.getBasicBlock(), b2)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -271,16 +271,24 @@ private predicate uniqueValue(SsaVariable v, Expr e, AbstractValue k) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `v1` and `v2` have the same value in `bb`.
|
||||
*/
|
||||
private predicate equalVarsInBlock(BasicBlock bb, SsaVariable v1, SsaVariable v2) {
|
||||
exists(Guard guard, boolean branch |
|
||||
guard.isEquality(v1.getAUse(), v2.getAUse(), branch) and
|
||||
guardControls_v1(guard, bb, branch)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `guard` evaluating to `branch` implies that `v` equals `k`.
|
||||
*/
|
||||
private predicate guardImpliesEqual(Guard guard, boolean branch, SsaVariable v, AbstractValue k) {
|
||||
guard.isEquality(v.getAUse(), k.getExpr(), branch)
|
||||
}
|
||||
|
||||
private BasicBlock getBasicBlockOfGuard(Guard g) {
|
||||
result = g.(Expr).getControlFlowNode().getBasicBlock() or
|
||||
result = g.(SwitchCase).getSwitch().getExpr().getProperExpr().getControlFlowNode().getBasicBlock()
|
||||
exists(SsaVariable v0 |
|
||||
guard.isEquality(v0.getAUse(), k.getExpr(), branch) and
|
||||
(v = v0 or equalVarsInBlock(guard.getBasicBlock(), v0, v))
|
||||
)
|
||||
}
|
||||
|
||||
private ControlFlowNode getAGuardBranchSuccessor(Guard g, boolean branch) {
|
||||
@@ -299,7 +307,7 @@ private predicate guardControlsPhiBranch(
|
||||
guard.directlyControls(upd.getBasicBlock(), branch) and
|
||||
upd.getDefiningExpr().(VariableAssign).getSource().getProperExpr() = e and
|
||||
upd = phi.getAPhiInput() and
|
||||
getBasicBlockOfGuard(guard).bbStrictlyDominates(phi.getBasicBlock())
|
||||
guard.getBasicBlock().bbStrictlyDominates(phi.getBasicBlock())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -326,7 +334,7 @@ private predicate conditionalAssign(SsaVariable v, Guard guard, boolean branch,
|
||||
forall(SsaVariable other | other != upd and other = phi.getAPhiInput() |
|
||||
guard.directlyControls(other.getBasicBlock(), branch.booleanNot())
|
||||
or
|
||||
other.getBasicBlock().bbDominates(getBasicBlockOfGuard(guard)) and
|
||||
other.getBasicBlock().bbDominates(guard.getBasicBlock()) and
|
||||
not other.isLiveAtEndOfBlock(getAGuardBranchSuccessor(guard, branch))
|
||||
)
|
||||
)
|
||||
@@ -341,6 +349,11 @@ private predicate conditionalAssignVal(SsaVariable v, Guard guard, boolean branc
|
||||
|
||||
private predicate relevantEq(SsaVariable v, AbstractValue val) {
|
||||
conditionalAssignVal(v, _, _, val)
|
||||
or
|
||||
exists(SsaVariable v0 |
|
||||
conditionalAssignVal(v0, _, _, val) and
|
||||
equalVarsInBlock(_, v0, v)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -349,16 +362,19 @@ private predicate relevantEq(SsaVariable v, AbstractValue val) {
|
||||
private predicate guardImpliesNotEqual1(
|
||||
Guard guard, boolean branch, SsaVariable v, AbstractValue val
|
||||
) {
|
||||
relevantEq(v, val) and
|
||||
(
|
||||
guard.isEquality(v.getAUse(), val.getExpr(), branch.booleanNot())
|
||||
or
|
||||
exists(AbstractValue val2 |
|
||||
guard.isEquality(v.getAUse(), val2.getExpr(), branch) and
|
||||
val != val2
|
||||
)
|
||||
or
|
||||
guard.(InstanceOfExpr).getExpr() = sameValue(v, _) and branch = true and val = TAbsValNull()
|
||||
exists(SsaVariable v0 |
|
||||
relevantEq(v0, val) and
|
||||
(
|
||||
guard.isEquality(v0.getAUse(), val.getExpr(), branch.booleanNot())
|
||||
or
|
||||
exists(AbstractValue val2 |
|
||||
guard.isEquality(v0.getAUse(), val2.getExpr(), branch) and
|
||||
val != val2
|
||||
)
|
||||
or
|
||||
guard.(InstanceOfExpr).getExpr() = sameValue(v0, _) and branch = true and val = TAbsValNull()
|
||||
) and
|
||||
(v = v0 or equalVarsInBlock(guard.getBasicBlock(), v0, v))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -368,13 +384,16 @@ private predicate guardImpliesNotEqual1(
|
||||
private predicate guardImpliesNotEqual2(
|
||||
Guard guard, boolean branch, SsaVariable v, AbstractValue val
|
||||
) {
|
||||
relevantEq(v, val) and
|
||||
(
|
||||
guard = directNullGuard(v, branch, false) and val = TAbsValNull()
|
||||
or
|
||||
exists(int k |
|
||||
guard = integerGuard(v.getAUse(), branch, k, false) and
|
||||
val = TAbsValInt(k)
|
||||
)
|
||||
exists(SsaVariable v0 |
|
||||
relevantEq(v0, val) and
|
||||
(
|
||||
guard = directNullGuard(v0, branch, false) and val = TAbsValNull()
|
||||
or
|
||||
exists(int k |
|
||||
guard = integerGuard(v0.getAUse(), branch, k, false) and
|
||||
val = TAbsValInt(k)
|
||||
)
|
||||
) and
|
||||
(v = v0 or equalVarsInBlock(guard.getBasicBlock(), v0, v))
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user