mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge branch 'main' into post-release-prep/codeql-cli-2.23.6
This commit is contained in:
5
.github/workflows/build-ripunzip.yml
vendored
5
.github/workflows/build-ripunzip.yml
vendored
@@ -46,7 +46,10 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-24.04, macos-15, windows-2025]
|
||||
os:
|
||||
- ubuntu-22.04 # keep at lowest supported ubuntu version for broader glibc compatibility
|
||||
- macos-15
|
||||
- windows-2025
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
4
java/ql/lib/change-notes/2025-10-07-ssa-api-updates.md
Normal file
4
java/ql/lib/change-notes/2025-10-07-ssa-api-updates.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* The SSA interface has been updated and all classes and several predicates have been renamed. See the qldoc for more specific migration information.
|
||||
@@ -1808,6 +1808,52 @@ class VariableAssign extends VariableUpdate {
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TVariableWrite =
|
||||
TParamInit(Parameter p) or
|
||||
TVarWriteExpr(VariableUpdate u)
|
||||
|
||||
/**
|
||||
* A write to a variable. This is either a local variable declaration,
|
||||
* including parameter declarations, or an update to a variable.
|
||||
*/
|
||||
class VariableWrite extends TVariableWrite {
|
||||
/** Gets the expression representing this write, if any. */
|
||||
Expr asExpr() { this = TVarWriteExpr(result) }
|
||||
|
||||
/**
|
||||
* Gets the expression with the value being written, if any.
|
||||
*
|
||||
* This can be the same expression as returned by `asExpr()`, which is the
|
||||
* case for, for example, `++x` and `x += e`. For simple assignments like
|
||||
* `x = e`, `asExpr()` gets the whole assignment expression while
|
||||
* `getValue()` gets the right-hand side `e`. Post-crement operations like
|
||||
* `x++` do not have an expression with the value being written.
|
||||
*/
|
||||
Expr getValue() {
|
||||
this.asExpr().(VariableAssign).getSource() = result or
|
||||
this.asExpr().(AssignOp) = result or
|
||||
this.asExpr().(PreIncExpr) = result or
|
||||
this.asExpr().(PreDecExpr) = result
|
||||
}
|
||||
|
||||
/** Holds if this write is an initialization of parameter `p`. */
|
||||
predicate isParameterInit(Parameter p) { this = TParamInit(p) }
|
||||
|
||||
/** Gets a textual representation of this write. */
|
||||
string toString() {
|
||||
exists(Parameter p | this = TParamInit(p) and result = p.toString())
|
||||
or
|
||||
result = this.asExpr().toString()
|
||||
}
|
||||
|
||||
/** Gets the location of this write. */
|
||||
Location getLocation() {
|
||||
exists(Parameter p | this = TParamInit(p) and result = p.getLocation())
|
||||
or
|
||||
result = this.asExpr().getLocation()
|
||||
}
|
||||
}
|
||||
|
||||
/** A type literal. For example, `String.class`. */
|
||||
class TypeLiteral extends Expr, @typeliteral {
|
||||
/** Gets the access to the type whose class is accessed. */
|
||||
|
||||
@@ -6,11 +6,12 @@ module;
|
||||
|
||||
import java
|
||||
private import codeql.controlflow.ControlFlowReachability
|
||||
private import semmle.code.java.dataflow.SSA as SSA
|
||||
private import semmle.code.java.dataflow.SSA
|
||||
private import semmle.code.java.controlflow.Guards as Guards
|
||||
|
||||
private module ControlFlowInput implements InputSig<Location, ControlFlowNode, BasicBlock> {
|
||||
private import java as J
|
||||
import Ssa
|
||||
|
||||
AstNode getEnclosingAstNode(ControlFlowNode node) { node.getAstNode() = result }
|
||||
|
||||
@@ -27,23 +28,6 @@ private module ControlFlowInput implements InputSig<Location, ControlFlowNode, B
|
||||
|
||||
class Expr = J::Expr;
|
||||
|
||||
class SourceVariable = SSA::SsaSourceVariable;
|
||||
|
||||
class SsaDefinition = SSA::SsaVariable;
|
||||
|
||||
class SsaExplicitWrite extends SsaDefinition instanceof SSA::SsaExplicitUpdate {
|
||||
Expr getValue() {
|
||||
super.getDefiningExpr().(VariableAssign).getSource() = result or
|
||||
super.getDefiningExpr().(AssignOp) = result
|
||||
}
|
||||
}
|
||||
|
||||
class SsaPhiDefinition = SSA::SsaPhiNode;
|
||||
|
||||
class SsaUncertainWrite extends SsaDefinition instanceof SSA::SsaUncertainImplicitUpdate {
|
||||
SsaDefinition getPriorDefinition() { result = super.getPriorDef() }
|
||||
}
|
||||
|
||||
class GuardValue = Guards::GuardValue;
|
||||
|
||||
predicate ssaControlsBranchEdge(SsaDefinition def, BasicBlock bb1, BasicBlock bb2, GuardValue v) {
|
||||
|
||||
@@ -141,7 +141,7 @@ private predicate isNonFallThroughPredecessor(SwitchCase sc, ControlFlowNode pre
|
||||
|
||||
private module GuardsInput implements SharedGuards::InputSig<Location, ControlFlowNode, BasicBlock> {
|
||||
private import java as J
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA as Base
|
||||
private import semmle.code.java.dataflow.NullGuards as NullGuards
|
||||
|
||||
class NormalExitNode = ControlFlow::NormalExitNode;
|
||||
@@ -211,10 +211,10 @@ private module GuardsInput implements SharedGuards::InputSig<Location, ControlFl
|
||||
f.getInitializer() = NullGuards::baseNotNullExpr()
|
||||
)
|
||||
or
|
||||
exists(CatchClause cc, LocalVariableDeclExpr decl, BaseSsaUpdate v |
|
||||
exists(CatchClause cc, LocalVariableDeclExpr decl, Base::SsaExplicitWrite v |
|
||||
decl = cc.getVariable() and
|
||||
decl = v.getDefiningExpr() and
|
||||
this = v.getAUse()
|
||||
this = v.getARead()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -407,30 +407,8 @@ private module LogicInputCommon {
|
||||
}
|
||||
|
||||
private module LogicInput_v1 implements GuardsImpl::LogicInputSig {
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA
|
||||
|
||||
final private class FinalBaseSsaVariable = BaseSsaVariable;
|
||||
|
||||
class SsaDefinition extends FinalBaseSsaVariable {
|
||||
GuardsInput::Expr getARead() { result = this.getAUse() }
|
||||
}
|
||||
|
||||
class SsaExplicitWrite extends SsaDefinition instanceof BaseSsaUpdate {
|
||||
GuardsInput::Expr getValue() {
|
||||
super.getDefiningExpr().(VariableAssign).getSource() = result or
|
||||
super.getDefiningExpr().(AssignOp) = result
|
||||
}
|
||||
}
|
||||
|
||||
class SsaPhiDefinition extends SsaDefinition instanceof BaseSsaPhiNode {
|
||||
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb) {
|
||||
super.hasInputFromBlock(inp, bb)
|
||||
}
|
||||
}
|
||||
|
||||
class SsaParameterInit extends SsaDefinition instanceof BaseSsaImplicitInit {
|
||||
Parameter getParameter() { super.isParameterDefinition(result) }
|
||||
}
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA as Base
|
||||
import Base::Ssa
|
||||
|
||||
predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4;
|
||||
|
||||
@@ -438,30 +416,8 @@ private module LogicInput_v1 implements GuardsImpl::LogicInputSig {
|
||||
}
|
||||
|
||||
private module LogicInput_v2 implements GuardsImpl::LogicInputSig {
|
||||
private import semmle.code.java.dataflow.SSA as SSA
|
||||
|
||||
final private class FinalSsaVariable = SSA::SsaVariable;
|
||||
|
||||
class SsaDefinition extends FinalSsaVariable {
|
||||
GuardsInput::Expr getARead() { result = this.getAUse() }
|
||||
}
|
||||
|
||||
class SsaExplicitWrite extends SsaDefinition instanceof SSA::SsaExplicitUpdate {
|
||||
GuardsInput::Expr getValue() {
|
||||
super.getDefiningExpr().(VariableAssign).getSource() = result or
|
||||
super.getDefiningExpr().(AssignOp) = result
|
||||
}
|
||||
}
|
||||
|
||||
class SsaPhiDefinition extends SsaDefinition instanceof SSA::SsaPhiNode {
|
||||
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb) {
|
||||
super.hasInputFromBlock(inp, bb)
|
||||
}
|
||||
}
|
||||
|
||||
class SsaParameterInit extends SsaDefinition instanceof SSA::SsaImplicitInit {
|
||||
Parameter getParameter() { super.isParameterDefinition(result) }
|
||||
}
|
||||
private import semmle.code.java.dataflow.SSA
|
||||
import Ssa
|
||||
|
||||
predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4;
|
||||
|
||||
|
||||
@@ -34,8 +34,12 @@ predicate useUsePair(VarRead use1, VarRead use2) { adjacentUseUse+(use1, use2) }
|
||||
* Other paths may also exist, so the SSA variables in `def` and `use` can be different.
|
||||
*/
|
||||
predicate defUsePair(VariableUpdate def, VarRead use) {
|
||||
exists(SsaVariable v |
|
||||
v.getAUse() = use and v.getAnUltimateDefinition().(SsaExplicitUpdate).getDefiningExpr() = def
|
||||
exists(SsaDefinition v, SsaExplicitWrite write |
|
||||
v.getARead() = use and write.getDefiningExpr() = def
|
||||
|
|
||||
v.getAnUltimateDefinition() = write
|
||||
or
|
||||
v.(SsaCapturedDefinition).getAnUltimateCapturedDefinition() = write
|
||||
)
|
||||
}
|
||||
|
||||
@@ -46,7 +50,9 @@ predicate defUsePair(VariableUpdate def, VarRead use) {
|
||||
* Other paths may also exist, so the SSA variables can be different.
|
||||
*/
|
||||
predicate parameterDefUsePair(Parameter p, VarRead use) {
|
||||
exists(SsaVariable v |
|
||||
v.getAUse() = use and v.getAnUltimateDefinition().(SsaImplicitInit).isParameterDefinition(p)
|
||||
exists(SsaDefinition v, SsaParameterInit init | v.getARead() = use and init.getParameter() = p |
|
||||
v.getAnUltimateDefinition() = init
|
||||
or
|
||||
v.(SsaCapturedDefinition).getAnUltimateCapturedDefinition() = init
|
||||
)
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@ Expr enumConstEquality(Expr e, boolean polarity, EnumConstant c) {
|
||||
}
|
||||
|
||||
/** Gets an instanceof expression of `v` with type `type` */
|
||||
InstanceOfExpr instanceofExpr(SsaVariable v, RefType type) {
|
||||
InstanceOfExpr instanceofExpr(SsaDefinition v, RefType type) {
|
||||
result.getCheckedType() = type and
|
||||
result.getExpr() = v.getAUse()
|
||||
result.getExpr() = v.getARead()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,8 +37,8 @@ InstanceOfExpr instanceofExpr(SsaVariable v, RefType type) {
|
||||
*
|
||||
* Note this includes Kotlin's `==` and `!=` operators, which are value-equality tests.
|
||||
*/
|
||||
EqualityTest varEqualityTestExpr(SsaVariable v1, SsaVariable v2, boolean isEqualExpr) {
|
||||
result.hasOperands(v1.getAUse(), v2.getAUse()) and
|
||||
EqualityTest varEqualityTestExpr(SsaDefinition v1, SsaDefinition v2, boolean isEqualExpr) {
|
||||
result.hasOperands(v1.getARead(), v2.getARead()) and
|
||||
isEqualExpr = result.polarity()
|
||||
}
|
||||
|
||||
@@ -91,37 +91,44 @@ Expr clearlyNotNullExpr(Expr reason) {
|
||||
(reason = r1 or reason = r2)
|
||||
)
|
||||
or
|
||||
exists(SsaVariable v, boolean branch, VarRead rval, Guard guard |
|
||||
exists(SsaDefinition v, boolean branch, VarRead rval, Guard guard |
|
||||
guard = directNullGuard(v, branch, false) and
|
||||
guard.controls(rval.getBasicBlock(), branch) and
|
||||
reason = guard and
|
||||
rval = v.getAUse() and
|
||||
rval = v.getARead() and
|
||||
result = rval and
|
||||
not result = baseNotNullExpr()
|
||||
)
|
||||
or
|
||||
exists(SsaVariable v |
|
||||
exists(SsaDefinition v |
|
||||
clearlyNotNull(v, reason) and
|
||||
result = v.getAUse() and
|
||||
result = v.getARead() and
|
||||
not result = baseNotNullExpr()
|
||||
)
|
||||
or
|
||||
exists(Field f |
|
||||
result = f.getAnAccess() and
|
||||
f.isFinal() and
|
||||
f.getInitializer() = clearlyNotNullExpr(reason) and
|
||||
not result = baseNotNullExpr()
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `v` is an SSA variable that is provably not `null`. */
|
||||
predicate clearlyNotNull(SsaVariable v, Expr reason) {
|
||||
predicate clearlyNotNull(SsaDefinition v, Expr reason) {
|
||||
exists(Expr src |
|
||||
src = v.(SsaExplicitUpdate).getDefiningExpr().(VariableAssign).getSource() and
|
||||
src = v.(SsaExplicitWrite).getValue() and
|
||||
src = clearlyNotNullExpr(reason)
|
||||
)
|
||||
or
|
||||
exists(CatchClause cc, LocalVariableDeclExpr decl |
|
||||
decl = cc.getVariable() and
|
||||
decl = v.(SsaExplicitUpdate).getDefiningExpr() and
|
||||
decl = v.(SsaExplicitWrite).getDefiningExpr() and
|
||||
reason = decl
|
||||
)
|
||||
or
|
||||
exists(SsaVariable captured |
|
||||
v.(SsaImplicitInit).captures(captured) and
|
||||
exists(SsaDefinition captured |
|
||||
v.(SsaCapturedDefinition).captures(captured) and
|
||||
clearlyNotNull(captured, reason)
|
||||
)
|
||||
or
|
||||
@@ -136,7 +143,7 @@ predicate clearlyNotNull(SsaVariable v, Expr reason) {
|
||||
Expr clearlyNotNullExpr() { result = clearlyNotNullExpr(_) }
|
||||
|
||||
/** Holds if `v` is an SSA variable that is provably not `null`. */
|
||||
predicate clearlyNotNull(SsaVariable v) { clearlyNotNull(v, _) }
|
||||
predicate clearlyNotNull(SsaDefinition v) { clearlyNotNull(v, _) }
|
||||
|
||||
/**
|
||||
* Holds if the evaluation of a call to `m` resulting in the value `branch`
|
||||
@@ -207,7 +214,7 @@ deprecated Expr basicOrCustomNullGuard(Expr e, boolean branch, boolean isnull) {
|
||||
* If `result` evaluates to `branch`, then `v` is guaranteed to be null if `isnull`
|
||||
* is true, and non-null if `isnull` is false.
|
||||
*/
|
||||
Expr directNullGuard(SsaVariable v, boolean branch, boolean isnull) {
|
||||
Expr directNullGuard(SsaDefinition v, boolean branch, boolean isnull) {
|
||||
result = basicNullGuard(sameValue(v, _), branch, isnull)
|
||||
}
|
||||
|
||||
@@ -219,7 +226,7 @@ Expr directNullGuard(SsaVariable v, boolean branch, boolean isnull) {
|
||||
* If `result` evaluates to `branch`, then `v` is guaranteed to be null if `isnull`
|
||||
* is true, and non-null if `isnull` is false.
|
||||
*/
|
||||
deprecated Guard nullGuard(SsaVariable v, boolean branch, boolean isnull) {
|
||||
deprecated Guard nullGuard(SsaDefinition v, boolean branch, boolean isnull) {
|
||||
result = directNullGuard(v, branch, isnull)
|
||||
}
|
||||
|
||||
@@ -228,7 +235,9 @@ deprecated Guard nullGuard(SsaVariable v, boolean branch, boolean isnull) {
|
||||
* from `bb1` to `bb2` implies that `v` is guaranteed to be null if `isnull` is
|
||||
* true, and non-null if `isnull` is false.
|
||||
*/
|
||||
predicate nullGuardControlsBranchEdge(SsaVariable v, boolean isnull, BasicBlock bb1, BasicBlock bb2) {
|
||||
predicate nullGuardControlsBranchEdge(
|
||||
SsaDefinition v, boolean isnull, BasicBlock bb1, BasicBlock bb2
|
||||
) {
|
||||
exists(GuardValue gv |
|
||||
Guards_v3::ssaControlsBranchEdge(v, bb1, bb2, gv) and
|
||||
gv.isNullness(isnull)
|
||||
@@ -240,7 +249,7 @@ predicate nullGuardControlsBranchEdge(SsaVariable v, boolean isnull, BasicBlock
|
||||
* `bb` `v` is guaranteed to be null if `isnull` is true, and non-null if
|
||||
* `isnull` is false.
|
||||
*/
|
||||
predicate nullGuardControls(SsaVariable v, boolean isnull, BasicBlock bb) {
|
||||
predicate nullGuardControls(SsaDefinition v, boolean isnull, BasicBlock bb) {
|
||||
exists(GuardValue gv |
|
||||
Guards_v3::ssaControls(v, bb, gv) and
|
||||
gv.isNullness(isnull)
|
||||
@@ -263,6 +272,6 @@ predicate guardSuggestsExprMaybeNull(Expr guard, Expr e) {
|
||||
/**
|
||||
* Holds if `guard` is a guard expression that suggests that `v` might be null.
|
||||
*/
|
||||
predicate guardSuggestsVarMaybeNull(Expr guard, SsaVariable v) {
|
||||
predicate guardSuggestsVarMaybeNull(Expr guard, SsaDefinition v) {
|
||||
guardSuggestsExprMaybeNull(guard, sameValue(v, _))
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ predicate dereference(Expr e) {
|
||||
*
|
||||
* The `VarAccess` is included for nicer error reporting.
|
||||
*/
|
||||
private ControlFlowNode varDereference(SsaVariable v, VarAccess va) {
|
||||
private ControlFlowNode varDereference(SsaDefinition v, VarAccess va) {
|
||||
dereference(result.asExpr()) and
|
||||
result.asExpr() = sameValue(v, va)
|
||||
}
|
||||
@@ -121,7 +121,7 @@ private ControlFlowNode varDereference(SsaVariable v, VarAccess va) {
|
||||
/**
|
||||
* The first dereference of a variable in a given `BasicBlock`.
|
||||
*/
|
||||
private predicate firstVarDereferenceInBlock(BasicBlock bb, SsaVariable v, VarAccess va) {
|
||||
private predicate firstVarDereferenceInBlock(BasicBlock bb, SsaDefinition v, VarAccess va) {
|
||||
exists(ControlFlowNode n |
|
||||
varDereference(v, va) = n and
|
||||
n.getBasicBlock() = bb and
|
||||
@@ -135,14 +135,14 @@ private predicate firstVarDereferenceInBlock(BasicBlock bb, SsaVariable v, VarAc
|
||||
}
|
||||
|
||||
/** A variable suspected of being `null`. */
|
||||
private predicate varMaybeNull(SsaVariable v, ControlFlowNode node, string msg, Expr reason) {
|
||||
private predicate varMaybeNull(SsaDefinition v, ControlFlowNode node, string msg, Expr reason) {
|
||||
// A variable compared to null might be null.
|
||||
exists(Expr e |
|
||||
reason = e and
|
||||
msg = "as suggested by $@ null guard" and
|
||||
guardSuggestsVarMaybeNull(e, v) and
|
||||
node = v.getCfgNode() and
|
||||
not v instanceof SsaPhiNode and
|
||||
node = v.getControlFlowNode() and
|
||||
not v instanceof SsaPhiDefinition and
|
||||
not clearlyNotNull(v) and
|
||||
// Comparisons in finally blocks are excluded since missing exception edges in the CFG could otherwise yield FPs.
|
||||
not exists(TryStmt try | try.getFinally() = e.getEnclosingStmt().getEnclosingStmt*()) and
|
||||
@@ -151,13 +151,13 @@ private predicate varMaybeNull(SsaVariable v, ControlFlowNode node, string msg,
|
||||
not exists(MethodCall ma | ma.getAnArgument().getAChildExpr*() = e)
|
||||
) and
|
||||
// Don't use a guard as reason if there is a null assignment.
|
||||
not v.(SsaExplicitUpdate).getDefiningExpr().(VariableAssign).getSource() = nullExpr()
|
||||
not v.(SsaExplicitWrite).getDefiningExpr().(VariableAssign).getSource() = nullExpr()
|
||||
)
|
||||
or
|
||||
// A parameter might be null if there is a null argument somewhere.
|
||||
exists(Parameter p, Expr arg |
|
||||
v.(SsaImplicitInit).isParameterDefinition(p) and
|
||||
node = v.getCfgNode() and
|
||||
v.(SsaParameterInit).getParameter() = p and
|
||||
node = v.getControlFlowNode() and
|
||||
p.getAnArgument() = arg and
|
||||
reason = arg and
|
||||
msg = "because of $@ null argument" and
|
||||
@@ -167,7 +167,7 @@ private predicate varMaybeNull(SsaVariable v, ControlFlowNode node, string msg,
|
||||
or
|
||||
// If the source of a variable is null then the variable may be null.
|
||||
exists(VariableAssign def |
|
||||
v.(SsaExplicitUpdate).getDefiningExpr() = def and
|
||||
v.(SsaExplicitWrite).getDefiningExpr() = def and
|
||||
def.getSource() = nullExpr(node.asExpr()) and
|
||||
reason = def and
|
||||
msg = "because of $@ assignment"
|
||||
@@ -179,26 +179,26 @@ private Expr nonEmptyExpr() {
|
||||
// An array creation with a known positive size is trivially non-empty.
|
||||
result.(ArrayCreationExpr).getFirstDimensionSize() > 0
|
||||
or
|
||||
exists(SsaVariable v |
|
||||
exists(SsaDefinition v |
|
||||
// A use of an array variable is non-empty if...
|
||||
result = v.getAUse() and
|
||||
result = v.getARead() and
|
||||
v.getSourceVariable().getType() instanceof Array
|
||||
|
|
||||
// ...its definition is non-empty...
|
||||
v.(SsaExplicitUpdate).getDefiningExpr().(VariableAssign).getSource() = nonEmptyExpr()
|
||||
v.(SsaExplicitWrite).getValue() = nonEmptyExpr()
|
||||
or
|
||||
// ...or it is guarded by a condition proving its length to be non-zero.
|
||||
exists(ConditionBlock cond, boolean branch, FieldAccess length |
|
||||
cond.controls(result.getBasicBlock(), branch) and
|
||||
cond.getCondition() = nonZeroGuard(length, branch) and
|
||||
length.getField().hasName("length") and
|
||||
length.getQualifier() = v.getAUse()
|
||||
length.getQualifier() = v.getARead()
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(SsaVariable v |
|
||||
exists(SsaDefinition v |
|
||||
// A use of a Collection variable is non-empty if...
|
||||
result = v.getAUse() and
|
||||
result = v.getARead() and
|
||||
v.getSourceVariable().getType() instanceof CollectionType and
|
||||
exists(ConditionBlock cond, boolean branch, Expr c |
|
||||
// ...it is guarded by a condition...
|
||||
@@ -216,13 +216,13 @@ private Expr nonEmptyExpr() {
|
||||
// ...and the condition proves that it is non-empty, either by using the `isEmpty` method...
|
||||
c.(MethodCall).getMethod().hasName("isEmpty") and
|
||||
branch = false and
|
||||
c.(MethodCall).getQualifier() = v.getAUse()
|
||||
c.(MethodCall).getQualifier() = v.getARead()
|
||||
or
|
||||
// ...or a check on its `size`.
|
||||
exists(MethodCall size |
|
||||
c = nonZeroGuard(size, branch) and
|
||||
size.getMethod().hasName("size") and
|
||||
size.getQualifier() = v.getAUse()
|
||||
size.getQualifier() = v.getARead()
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -249,9 +249,9 @@ private predicate impossibleEdge(BasicBlock bb1, BasicBlock bb2) {
|
||||
}
|
||||
|
||||
private module NullnessConfig implements ControlFlowReachability::ConfigSig {
|
||||
predicate source(ControlFlowNode node, SsaVariable def) { varMaybeNull(def, node, _, _) }
|
||||
predicate source(ControlFlowNode node, SsaDefinition def) { varMaybeNull(def, node, _, _) }
|
||||
|
||||
predicate sink(ControlFlowNode node, SsaVariable def) { varDereference(def, _) = node }
|
||||
predicate sink(ControlFlowNode node, SsaDefinition def) { varDereference(def, _) = node }
|
||||
|
||||
predicate barrierValue(GuardValue gv) { gv.isNullness(false) }
|
||||
|
||||
@@ -266,7 +266,7 @@ private module NullnessFlow = ControlFlowReachability::Flow<NullnessConfig>;
|
||||
* Holds if the dereference of `v` at `va` might be `null`.
|
||||
*/
|
||||
predicate nullDeref(SsaSourceVariable v, VarAccess va, string msg, Expr reason) {
|
||||
exists(SsaVariable origin, SsaVariable ssa, ControlFlowNode src, ControlFlowNode sink |
|
||||
exists(SsaDefinition origin, SsaDefinition ssa, ControlFlowNode src, ControlFlowNode sink |
|
||||
varMaybeNull(origin, src, msg, reason) and
|
||||
NullnessFlow::flow(src, origin, sink, ssa) and
|
||||
ssa.getSourceVariable() = v and
|
||||
@@ -278,9 +278,9 @@ predicate nullDeref(SsaSourceVariable v, VarAccess va, string msg, Expr reason)
|
||||
* A dereference of a variable that is always `null`.
|
||||
*/
|
||||
predicate alwaysNullDeref(SsaSourceVariable v, VarAccess va) {
|
||||
exists(BasicBlock bb, SsaVariable ssa |
|
||||
forall(SsaVariable def | def = ssa.getAnUltimateDefinition() |
|
||||
def.(SsaExplicitUpdate).getDefiningExpr().(VariableAssign).getSource() = alwaysNullExpr()
|
||||
exists(BasicBlock bb, SsaDefinition ssa |
|
||||
forall(SsaDefinition def | def = ssa.getAnUltimateDefinition() |
|
||||
def.(SsaExplicitWrite).getValue() = alwaysNullExpr()
|
||||
)
|
||||
or
|
||||
nullGuardControls(ssa, true, bb) and
|
||||
|
||||
@@ -242,17 +242,17 @@ module Sem implements Semantic<Location> {
|
||||
|
||||
Type getSsaType(SsaVariable var) { result = var.getSourceVariable().getType() }
|
||||
|
||||
final private class FinalSsaVariable = SSA::SsaVariable;
|
||||
final private class FinalSsaVariable = SSA::SsaDefinition;
|
||||
|
||||
class SsaVariable extends FinalSsaVariable {
|
||||
Expr getAUse() { result = super.getAUse() }
|
||||
Expr getAUse() { result = super.getARead() }
|
||||
}
|
||||
|
||||
class SsaPhiNode extends SsaVariable instanceof SSA::SsaPhiNode {
|
||||
class SsaPhiNode extends SsaVariable instanceof SSA::SsaPhiDefinition {
|
||||
predicate hasInputFromBlock(SsaVariable inp, BasicBlock bb) { super.hasInputFromBlock(inp, bb) }
|
||||
}
|
||||
|
||||
class SsaExplicitUpdate extends SsaVariable instanceof SSA::SsaExplicitUpdate {
|
||||
class SsaExplicitUpdate extends SsaVariable instanceof SSA::SsaExplicitWrite {
|
||||
Expr getDefiningExpr() { result = super.getDefiningExpr() }
|
||||
}
|
||||
|
||||
|
||||
@@ -30,17 +30,17 @@ predicate eqFlowCond = U::eqFlowCond/5;
|
||||
* only other input to `phi` is a `null` value.
|
||||
*
|
||||
* Note that the declared type of `phi` is `SsaVariable` instead of
|
||||
* `SsaPhiNode` in order for the reflexive case of `nonNullSsaFwdStep*(..)` to
|
||||
* have non-`SsaPhiNode` results.
|
||||
* `SsaPhiDefinition` in order for the reflexive case of `nonNullSsaFwdStep*(..)` to
|
||||
* have non-`SsaPhiDefinition` results.
|
||||
*/
|
||||
private predicate nonNullSsaFwdStep(SsaVariable v, SsaVariable phi) {
|
||||
exists(SsaExplicitUpdate vnull, SsaPhiNode phi0 | phi0 = phi |
|
||||
2 = strictcount(phi0.getAPhiInput()) and
|
||||
vnull = phi0.getAPhiInput() and
|
||||
v = phi0.getAPhiInput() and
|
||||
private predicate nonNullSsaFwdStep(SsaDefinition v, SsaDefinition phi) {
|
||||
exists(SsaExplicitWrite vnull, SsaPhiDefinition phi0 | phi0 = phi |
|
||||
2 = strictcount(phi0.getAnInput()) and
|
||||
vnull = phi0.getAnInput() and
|
||||
v = phi0.getAnInput() and
|
||||
not backEdge(phi0, v, _) and
|
||||
vnull != v and
|
||||
vnull.getDefiningExpr().(VariableAssign).getSource() instanceof NullLiteral
|
||||
vnull.getValue() instanceof NullLiteral
|
||||
)
|
||||
}
|
||||
|
||||
@@ -56,13 +56,13 @@ private predicate nonNullDefStep(Expr e1, Expr e2) {
|
||||
* explicit `ArrayCreationExpr` definition and that the definition does not go
|
||||
* through a back edge.
|
||||
*/
|
||||
ArrayCreationExpr getArrayDef(SsaVariable v) {
|
||||
ArrayCreationExpr getArrayDef(SsaDefinition v) {
|
||||
exists(Expr src |
|
||||
v.(SsaExplicitUpdate).getDefiningExpr().(VariableAssign).getSource() = src and
|
||||
v.(SsaExplicitWrite).getValue() = src and
|
||||
nonNullDefStep*(result, src)
|
||||
)
|
||||
or
|
||||
exists(SsaVariable mid |
|
||||
exists(SsaDefinition mid |
|
||||
result = getArrayDef(mid) and
|
||||
nonNullSsaFwdStep(mid, v)
|
||||
)
|
||||
@@ -74,9 +74,9 @@ ArrayCreationExpr getArrayDef(SsaVariable v) {
|
||||
* `arrlen` without going through a back edge.
|
||||
*/
|
||||
private predicate arrayLengthDef(FieldRead arrlen, ArrayCreationExpr def) {
|
||||
exists(SsaVariable arr |
|
||||
exists(SsaDefinition arr |
|
||||
arrlen.getField() instanceof ArrayLengthField and
|
||||
arrlen.getQualifier() = arr.getAUse() and
|
||||
arrlen.getQualifier() = arr.getARead() and
|
||||
def = getArrayDef(arr)
|
||||
)
|
||||
}
|
||||
@@ -86,9 +86,9 @@ pragma[nomagic]
|
||||
private predicate constantIntegerExpr(Expr e, int val) {
|
||||
e.(CompileTimeConstantExpr).getIntValue() = val
|
||||
or
|
||||
exists(SsaExplicitUpdate v, Expr src |
|
||||
e = v.getAUse() and
|
||||
src = v.getDefiningExpr().(VariableAssign).getSource() and
|
||||
exists(SsaExplicitWrite v, Expr src |
|
||||
e = v.getARead() and
|
||||
src = v.getValue() and
|
||||
constantIntegerExpr(src, val)
|
||||
)
|
||||
or
|
||||
@@ -112,9 +112,9 @@ pragma[nomagic]
|
||||
private predicate constantBooleanExpr(Expr e, boolean val) {
|
||||
e.(CompileTimeConstantExpr).getBooleanValue() = val
|
||||
or
|
||||
exists(SsaExplicitUpdate v, Expr src |
|
||||
e = v.getAUse() and
|
||||
src = v.getDefiningExpr().(VariableAssign).getSource() and
|
||||
exists(SsaExplicitWrite v, Expr src |
|
||||
e = v.getARead() and
|
||||
src = v.getValue() and
|
||||
constantBooleanExpr(src, val)
|
||||
)
|
||||
or
|
||||
@@ -125,9 +125,9 @@ pragma[nomagic]
|
||||
private predicate constantStringExpr(Expr e, string val) {
|
||||
e.(CompileTimeConstantExpr).getStringValue() = val
|
||||
or
|
||||
exists(SsaExplicitUpdate v, Expr src |
|
||||
e = v.getAUse() and
|
||||
src = v.getDefiningExpr().(VariableAssign).getSource() and
|
||||
exists(SsaExplicitWrite v, Expr src |
|
||||
e = v.getARead() and
|
||||
src = v.getValue() and
|
||||
constantStringExpr(src, val)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,16 +5,16 @@
|
||||
* `ControlFlowNode` at which it is defined. Each SSA variable is defined
|
||||
* either by a phi node, an implicit initial value (for parameters and fields),
|
||||
* an explicit update, or an implicit update (for fields).
|
||||
* An implicit update occurs either at a `Call` that might modify a field, at
|
||||
* another update that can update the qualifier of a field, or at a `FieldRead`
|
||||
* of the field in case the field is not amenable to a non-trivial SSA
|
||||
* representation.
|
||||
* An implicit update occurs either at a `Call` that might modify a field, or
|
||||
* at another update that can update the qualifier of a field.
|
||||
*/
|
||||
overlay[local?]
|
||||
module;
|
||||
|
||||
import java
|
||||
private import internal.SsaImpl
|
||||
import internal.SsaImpl::Ssa as Ssa
|
||||
import Ssa
|
||||
|
||||
/**
|
||||
* A fully qualified variable in the context of a `Callable` in which it is
|
||||
@@ -105,7 +105,7 @@ class SsaSourceVariable extends TSsaSourceVariable {
|
||||
SsaSourceVariable getQualifier() { this = TQualifiedField(_, result, _) }
|
||||
|
||||
/** Gets an SSA variable that has this variable as its underlying source variable. */
|
||||
SsaVariable getAnSsaVariable() { result.getSourceVariable() = this }
|
||||
SsaDefinition getAnSsaVariable() { result.getSourceVariable() = this }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,22 +138,76 @@ class SsaSourceField extends SsaSourceVariable {
|
||||
}
|
||||
}
|
||||
|
||||
/** An SSA definition in a closure that captures a variable. */
|
||||
class SsaCapturedDefinition extends SsaImplicitEntryDefinition {
|
||||
SsaCapturedDefinition() { captures(this, _) }
|
||||
|
||||
override string toString() { result = "SSA capture def(" + this.getSourceVariable() + ")" }
|
||||
|
||||
/** Holds if this definition captures the value of `capturedvar`. */
|
||||
predicate captures(SsaDefinition capturedvar) { captures(this, capturedvar) }
|
||||
|
||||
/**
|
||||
* Gets a definition that ultimately defines the captured variable and is not itself a phi node.
|
||||
*/
|
||||
SsaDefinition getAnUltimateCapturedDefinition() {
|
||||
exists(SsaDefinition capturedvar |
|
||||
captures(this, capturedvar) and result = capturedvar.getAnUltimateDefinition()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An SSA definition representing the potential definition of a variable
|
||||
* via a call.
|
||||
*/
|
||||
class SsaImplicitCallDefinition extends SsaImplicitWrite {
|
||||
SsaImplicitCallDefinition() { isNonLocal(this) and not hasQualifierUpdate(this) }
|
||||
|
||||
override string toString() { result = "SSA call def(" + this.getSourceVariable() + ")" }
|
||||
|
||||
/**
|
||||
* Gets a reachable `FieldWrite` that might represent this ssa update, if any.
|
||||
*/
|
||||
overlay[global]
|
||||
FieldWrite getANonLocalUpdate() { result = getANonLocalUpdate(this) }
|
||||
}
|
||||
|
||||
/** An SSA definition due to an update of the qualifier. */
|
||||
class SsaImplicitQualifierDefinition extends SsaImplicitWrite {
|
||||
SsaImplicitQualifierDefinition() { hasQualifierUpdate(this) }
|
||||
|
||||
override string toString() { result = "SSA qualifier def(" + this.getSourceVariable() + ")" }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an access of the SSA source variable underlying this SSA variable
|
||||
* that can be reached from this SSA variable without passing through any
|
||||
* other uses, but potentially through phi nodes and uncertain implicit
|
||||
* updates.
|
||||
*/
|
||||
VarRead ssaGetAFirstUse(SsaDefinition def) { firstUse(def, result) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `SsaDefinition` instead.
|
||||
*
|
||||
* An SSA variable.
|
||||
*/
|
||||
class SsaVariable extends Definition {
|
||||
/** Gets the SSA source variable underlying this SSA variable. */
|
||||
SsaSourceVariable getSourceVariable() { result = super.getSourceVariable() }
|
||||
|
||||
/** Gets the `ControlFlowNode` at which this SSA variable is defined. */
|
||||
/**
|
||||
* DEPRECATED: Use `getControlFlowNode()` instead.
|
||||
*
|
||||
* Gets the `ControlFlowNode` at which this SSA variable is defined.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
ControlFlowNode getCfgNode() {
|
||||
exists(BasicBlock bb, int i, int j |
|
||||
exists(BasicBlock bb, int i |
|
||||
this.definesAt(_, bb, i) and
|
||||
// untracked definitions are inserted just before reads
|
||||
(if this instanceof UntrackedDef then j = i + 1 else j = i) and
|
||||
// phi nodes are inserted at position `-1`
|
||||
result = bb.getNode(0.maximum(j))
|
||||
result = bb.getNode(0.maximum(i))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -166,10 +220,16 @@ class SsaVariable extends Definition {
|
||||
/** Gets the `BasicBlock` in which this SSA variable is defined. */
|
||||
BasicBlock getBasicBlock() { result = super.getBasicBlock() }
|
||||
|
||||
/** Gets an access of this SSA variable. */
|
||||
/**
|
||||
* DEPRECATED: Use `getARead()` instead.
|
||||
*
|
||||
* Gets an access of this SSA variable.
|
||||
*/
|
||||
VarRead getAUse() { result = getAUse(this) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `ssaGetAFirstUse(SsaDefinition)` instead.
|
||||
*
|
||||
* Gets an access of the SSA source variable underlying this SSA variable
|
||||
* that can be reached from this SSA variable without passing through any
|
||||
* other uses, but potentially through phi nodes and uncertain implicit
|
||||
@@ -178,34 +238,49 @@ class SsaVariable extends Definition {
|
||||
* Subsequent uses can be found by following the steps defined by
|
||||
* `adjacentUseUse`.
|
||||
*/
|
||||
VarRead getAFirstUse() { firstUse(this, result) }
|
||||
deprecated VarRead getAFirstUse() { firstUse(this, result) }
|
||||
|
||||
/** Holds if this SSA variable is live at the end of `b`. */
|
||||
predicate isLiveAtEndOfBlock(BasicBlock b) { ssaDefReachesEndOfBlock(b, this) }
|
||||
|
||||
/**
|
||||
* DEPRECATED.
|
||||
*
|
||||
* Gets an SSA variable whose value can flow to this one in one step. This
|
||||
* includes inputs to phi nodes, the prior definition of uncertain updates,
|
||||
* and the captured ssa variable for a closure variable.
|
||||
*/
|
||||
SsaVariable getAPhiInputOrPriorDef() {
|
||||
deprecated SsaVariable getAPhiInputOrPriorDef() {
|
||||
result = this.(SsaPhiNode).getAPhiInput() or
|
||||
result = this.(SsaUncertainImplicitUpdate).getPriorDef() or
|
||||
this.(SsaImplicitInit).captures(result)
|
||||
}
|
||||
|
||||
/** Gets a definition that ultimately defines this variable and is not itself a phi node. */
|
||||
SsaVariable getAnUltimateDefinition() {
|
||||
/**
|
||||
* DEPRECATED: Use `SsaCapturedDefinition::getAnUltimateCapturedDefinition()`
|
||||
* and/or `SsaDefinition::getAnUltimateDefinition()` instead.
|
||||
*
|
||||
* Gets a definition that ultimately defines this variable and is not itself a phi node.
|
||||
*/
|
||||
deprecated SsaVariable getAnUltimateDefinition() {
|
||||
result = this.getAPhiInputOrPriorDef*() and not result instanceof SsaPhiNode
|
||||
}
|
||||
}
|
||||
|
||||
/** An SSA variable that either explicitly or implicitly updates the variable. */
|
||||
/**
|
||||
* DEPRECATED: use `SsaWriteDefinition` instead.
|
||||
*
|
||||
* An SSA variable that either explicitly or implicitly updates the variable.
|
||||
*/
|
||||
class SsaUpdate extends SsaVariable instanceof WriteDefinition {
|
||||
SsaUpdate() { not this instanceof SsaImplicitInit }
|
||||
}
|
||||
|
||||
/** An SSA variable that is defined by a `VariableUpdate`. */
|
||||
/**
|
||||
* DEPRECATED: Use `SsaExplicitWrite` instead.
|
||||
*
|
||||
* An SSA variable that is defined by a `VariableUpdate`.
|
||||
*/
|
||||
class SsaExplicitUpdate extends SsaUpdate {
|
||||
private VariableUpdate upd;
|
||||
|
||||
@@ -218,12 +293,14 @@ class SsaExplicitUpdate extends SsaUpdate {
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `SsaImplicitWrite` instead.
|
||||
*
|
||||
* An SSA variable that represents any sort of implicit update. This can be a
|
||||
* `Call` that might reach a non-local update of the field, an explicit or
|
||||
* implicit update of the qualifier of the field, or the implicit update that
|
||||
* occurs just prior to a `FieldRead` of an untracked field.
|
||||
*/
|
||||
class SsaImplicitUpdate extends SsaUpdate {
|
||||
deprecated class SsaImplicitUpdate extends SsaUpdate {
|
||||
SsaImplicitUpdate() { not this instanceof SsaExplicitUpdate }
|
||||
|
||||
override string toString() {
|
||||
@@ -246,69 +323,89 @@ class SsaImplicitUpdate extends SsaUpdate {
|
||||
}
|
||||
|
||||
private string getKind() {
|
||||
this instanceof UntrackedDef and result = "untracked"
|
||||
or
|
||||
this.hasExplicitQualifierUpdate() and
|
||||
result = "explicit qualifier"
|
||||
result = "explicit qualifier" // -> SSA qualifier def
|
||||
or
|
||||
if this.hasImplicitQualifierUpdate()
|
||||
then
|
||||
if isNonLocal(this)
|
||||
then result = "nonlocal + nonlocal qualifier"
|
||||
else result = "nonlocal qualifier"
|
||||
then result = "nonlocal + nonlocal qualifier" // -> SSA qualifier def
|
||||
else result = "nonlocal qualifier" // -> SSA qualifier def
|
||||
else (
|
||||
isNonLocal(this) and result = "nonlocal"
|
||||
isNonLocal(this) and result = "nonlocal" // -> SSA call def
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `SsaImplicitCallDefinition.getANonLocalUpdate()` instead.
|
||||
*
|
||||
* Gets a reachable `FieldWrite` that might represent this ssa update, if any.
|
||||
*/
|
||||
overlay[global]
|
||||
FieldWrite getANonLocalUpdate() {
|
||||
exists(SsaSourceField f, Callable setter |
|
||||
relevantFieldUpdate(setter, f.getField(), result) and
|
||||
defUpdatesNamedField(this, f, setter)
|
||||
)
|
||||
}
|
||||
deprecated FieldWrite getANonLocalUpdate() { result = getANonLocalUpdate(this) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `SsaImplicitQualifierDefinition` instead.
|
||||
*
|
||||
* Holds if this ssa variable might change the value to something unknown.
|
||||
*
|
||||
* Examples include updates that might change the value of the qualifier, or
|
||||
* reads from untracked variables, for example those where the field or one
|
||||
* of its qualifiers is volatile.
|
||||
*/
|
||||
predicate assignsUnknownValue() {
|
||||
this instanceof UntrackedDef
|
||||
or
|
||||
deprecated predicate assignsUnknownValue() {
|
||||
this.hasExplicitQualifierUpdate()
|
||||
or
|
||||
this.hasImplicitQualifierUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
overlay[global]
|
||||
private predicate isNonLocalImpl(SsaImplicitUpdate su) { exists(su.getANonLocalUpdate()) }
|
||||
|
||||
private predicate isNonLocal(SsaImplicitUpdate su) = forceLocal(isNonLocalImpl/1)(su)
|
||||
private predicate hasQualifierUpdate(SsaImplicitWrite def) {
|
||||
exists(SsaWriteDefinition qdef, BasicBlock bb, int i |
|
||||
qdef.definesAt(def.getSourceVariable().getQualifier(), bb, i) and
|
||||
def.definesAt(_, bb, i) and
|
||||
not qdef instanceof SsaImplicitEntryDefinition
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reachable `FieldWrite` that might represent this ssa update, if any.
|
||||
*/
|
||||
overlay[global]
|
||||
private FieldWrite getANonLocalUpdate(SsaImplicitWrite calldef) {
|
||||
exists(SsaSourceField f, Callable setter |
|
||||
relevantFieldUpdate(setter, f.getField(), result) and
|
||||
defUpdatesNamedField(calldef, f, setter)
|
||||
)
|
||||
}
|
||||
|
||||
overlay[global]
|
||||
private predicate isNonLocalImpl(SsaImplicitWrite calldef) { exists(getANonLocalUpdate(calldef)) }
|
||||
|
||||
private predicate isNonLocal(SsaImplicitWrite calldef) = forceLocal(isNonLocalImpl/1)(calldef)
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `SsaUncertainWrite` instead.
|
||||
*
|
||||
* An SSA variable that represents an uncertain implicit update of the value.
|
||||
* This is a `Call` that might reach a non-local update of the field or one of
|
||||
* its qualifiers.
|
||||
*/
|
||||
class SsaUncertainImplicitUpdate extends SsaImplicitUpdate {
|
||||
deprecated class SsaUncertainImplicitUpdate extends SsaImplicitUpdate {
|
||||
SsaUncertainImplicitUpdate() { ssaUncertainImplicitUpdate(this) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getPriorDefinition()` instead.
|
||||
*
|
||||
* Gets the immediately preceding definition. Since this update is uncertain
|
||||
* the value from the preceding definition might still be valid.
|
||||
*/
|
||||
SsaVariable getPriorDef() { ssaDefReachesUncertainDef(result, this) }
|
||||
deprecated SsaVariable getPriorDef() { ssaDefReachesUncertainDef(result, this) }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `SsaParameterInit`, `SsaImplicitEntryDefinition`, or `SsaCapturedDefinition` instead.
|
||||
*
|
||||
* An SSA variable that is defined by its initial value in the callable. This
|
||||
* includes initial values of parameters, fields, and closure variables.
|
||||
*/
|
||||
@@ -321,6 +418,8 @@ class SsaImplicitInit extends SsaVariable instanceof WriteDefinition {
|
||||
predicate captures(SsaVariable capturedvar) { captures(this, capturedvar) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `SsaParameterInit::getParameter()` instead.
|
||||
*
|
||||
* Holds if the SSA variable is a parameter defined by its initial value in the callable.
|
||||
*/
|
||||
predicate isParameterDefinition(Parameter p) {
|
||||
@@ -329,12 +428,20 @@ class SsaImplicitInit extends SsaVariable instanceof WriteDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
/** An SSA phi node. */
|
||||
class SsaPhiNode extends SsaVariable instanceof PhiNode {
|
||||
/**
|
||||
* DEPRECATED: Use `SsaPhiDefinition` instead.
|
||||
*
|
||||
* An SSA phi node.
|
||||
*/
|
||||
deprecated class SsaPhiNode extends SsaVariable instanceof PhiNode {
|
||||
override string toString() { result = "SSA phi(" + this.getSourceVariable() + ")" }
|
||||
|
||||
/** Gets an input to the phi node defining the SSA variable. */
|
||||
SsaVariable getAPhiInput() { this.hasInputFromBlock(result, _) }
|
||||
/**
|
||||
* DEPRECATED: Use `getAnInput()` instead.
|
||||
*
|
||||
* Gets an input to the phi node defining the SSA variable.
|
||||
*/
|
||||
deprecated SsaVariable getAPhiInput() { this.hasInputFromBlock(result, _) }
|
||||
|
||||
/** Gets an input to the phi node defining the SSA variable. */
|
||||
SsaVariable getAnInput() { this.hasInputFromBlock(result, _) }
|
||||
@@ -357,10 +464,10 @@ private class RefTypeCastingExpr extends CastingExpr {
|
||||
*
|
||||
* The `VarAccess` represents the access to `v` that `result` has the same value as.
|
||||
*/
|
||||
Expr sameValue(SsaVariable v, VarAccess va) {
|
||||
result = v.getAUse() and result = va
|
||||
Expr sameValue(SsaDefinition v, VarAccess va) {
|
||||
result = v.getARead() and result = va
|
||||
or
|
||||
result.(AssignExpr).getDest() = va and result = v.(SsaExplicitUpdate).getDefiningExpr()
|
||||
result.(AssignExpr).getDest() = va and result = v.(SsaExplicitWrite).getDefiningExpr()
|
||||
or
|
||||
result.(AssignExpr).getSource() = sameValue(v, va)
|
||||
or
|
||||
|
||||
@@ -12,7 +12,7 @@ module;
|
||||
|
||||
import java as J
|
||||
private import semmle.code.java.dispatch.VirtualDispatch
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA as Base
|
||||
private import semmle.code.java.controlflow.Guards
|
||||
private import codeql.typeflow.TypeFlow
|
||||
private import codeql.typeflow.UniversalFlow as UniversalFlow
|
||||
@@ -27,7 +27,7 @@ private RefType boxIfNeeded(J::Type t) {
|
||||
module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
private newtype TFlowNode =
|
||||
TField(Field f) { not f.getType() instanceof PrimitiveType } or
|
||||
TSsa(BaseSsaVariable ssa) { not ssa.getSourceVariable().getType() instanceof PrimitiveType } or
|
||||
TSsa(Base::SsaDefinition ssa) { not ssa.getSourceVariable().getType() instanceof PrimitiveType } or
|
||||
TExpr(Expr e) or
|
||||
TMethod(Method m) { not m.getReturnType() instanceof PrimitiveType }
|
||||
|
||||
@@ -55,7 +55,7 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
Field asField() { this = TField(result) }
|
||||
|
||||
/** Gets the SSA variable corresponding to this node, if any. */
|
||||
BaseSsaVariable asSsa() { this = TSsa(result) }
|
||||
Base::SsaDefinition asSsa() { this = TSsa(result) }
|
||||
|
||||
/** Gets the expression corresponding to this node, if any. */
|
||||
Expr asExpr() { this = TExpr(result) }
|
||||
@@ -107,7 +107,7 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
not e.(FieldAccess).getField() = f
|
||||
)
|
||||
or
|
||||
n2.asSsa().(BaseSsaPhiNode).getAnUltimateLocalDefinition() = n1.asSsa()
|
||||
n2.asSsa().(Base::SsaPhiDefinition).getAnUltimateDefinition() = n1.asSsa()
|
||||
or
|
||||
exists(ReturnStmt ret |
|
||||
n2.asMethod() = ret.getEnclosingCallable() and ret.getResult() = n1.asExpr()
|
||||
@@ -118,14 +118,14 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
exists(Argument arg, Parameter p |
|
||||
privateParamArg(p, arg) and
|
||||
n1.asExpr() = arg and
|
||||
n2.asSsa().(BaseSsaImplicitInit).isParameterDefinition(p) and
|
||||
n2.asSsa().(Base::SsaParameterInit).getParameter() = p and
|
||||
// skip trivial recursion
|
||||
not arg = n2.asSsa().getAUse()
|
||||
not arg = n2.asSsa().getARead()
|
||||
)
|
||||
or
|
||||
n2.asExpr() = n1.asField().getAnAccess()
|
||||
or
|
||||
n2.asExpr() = n1.asSsa().getAUse()
|
||||
n2.asExpr() = n1.asSsa().getARead()
|
||||
or
|
||||
n2.asExpr().(CastingExpr).getExpr() = n1.asExpr() and
|
||||
not n2.asExpr().getType() instanceof PrimitiveType
|
||||
@@ -133,9 +133,9 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
n2.asExpr().(AssignExpr).getSource() = n1.asExpr() and
|
||||
not n2.asExpr().getType() instanceof PrimitiveType
|
||||
or
|
||||
n2.asSsa().(BaseSsaUpdate).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr()
|
||||
n2.asSsa().(Base::SsaExplicitWrite).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr()
|
||||
or
|
||||
n2.asSsa().(BaseSsaImplicitInit).captures(n1.asSsa())
|
||||
n2.asSsa().(Base::SsaCapturedDefinition).captures(n1.asSsa())
|
||||
or
|
||||
n2.asExpr().(NotNullExpr).getExpr() = n1.asExpr()
|
||||
}
|
||||
@@ -147,7 +147,7 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
n.asExpr() instanceof NullLiteral
|
||||
or
|
||||
exists(LocalVariableDeclExpr decl |
|
||||
n.asSsa().(BaseSsaUpdate).getDefiningExpr() = decl and
|
||||
n.asSsa().(Base::SsaExplicitWrite).getDefiningExpr() = decl and
|
||||
not decl.hasImplicitInit() and
|
||||
not exists(decl.getInitOrPatternSource())
|
||||
)
|
||||
@@ -216,7 +216,9 @@ private module Input implements TypeFlowInput<Location> {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate upcastEnhancedForStmtAux(BaseSsaUpdate v, RefType t, RefType t1, RefType t2) {
|
||||
private predicate upcastEnhancedForStmtAux(
|
||||
Base::SsaExplicitWrite v, RefType t, RefType t1, RefType t2
|
||||
) {
|
||||
exists(EnhancedForStmt for |
|
||||
for.getVariable() = v.getDefiningExpr() and
|
||||
v.getSourceVariable().getType().getErasure() = t2 and
|
||||
@@ -230,7 +232,7 @@ private module Input implements TypeFlowInput<Location> {
|
||||
* the type of the elements being iterated over, and this type is more precise
|
||||
* than the type of `v`.
|
||||
*/
|
||||
private predicate upcastEnhancedForStmt(BaseSsaUpdate v, RefType t) {
|
||||
private predicate upcastEnhancedForStmt(Base::SsaExplicitWrite v, RefType t) {
|
||||
exists(RefType t1, RefType t2 |
|
||||
upcastEnhancedForStmtAux(v, t, t1, t2) and
|
||||
t1.getASourceSupertype+() = t2
|
||||
@@ -238,9 +240,9 @@ private module Input implements TypeFlowInput<Location> {
|
||||
}
|
||||
|
||||
private predicate downcastSuccessorAux(
|
||||
CastingExpr cast, BaseSsaVariable v, RefType t, RefType t1, RefType t2
|
||||
CastingExpr cast, Base::SsaDefinition v, RefType t, RefType t1, RefType t2
|
||||
) {
|
||||
cast.getExpr() = v.getAUse() and
|
||||
cast.getExpr() = v.getARead() and
|
||||
t = cast.getType() and
|
||||
t1 = t.getErasure() and
|
||||
t2 = v.getSourceVariable().getType().getErasure()
|
||||
@@ -250,10 +252,10 @@ private module Input implements TypeFlowInput<Location> {
|
||||
* Holds if `va` is an access to a value that has previously been downcast to `t`.
|
||||
*/
|
||||
private predicate downcastSuccessor(VarAccess va, RefType t) {
|
||||
exists(CastingExpr cast, BaseSsaVariable v, RefType t1, RefType t2 |
|
||||
exists(CastingExpr cast, Base::SsaDefinition v, RefType t1, RefType t2 |
|
||||
downcastSuccessorAux(pragma[only_bind_into](cast), v, t, t1, t2) and
|
||||
t1.getASourceSupertype+() = t2 and
|
||||
va = v.getAUse() and
|
||||
va = v.getARead() and
|
||||
dominates(cast.getControlFlowNode(), va.getControlFlowNode()) and
|
||||
dominates(cast.getControlFlowNode().getANormalSuccessor(), va.getControlFlowNode())
|
||||
)
|
||||
@@ -263,9 +265,9 @@ private module Input implements TypeFlowInput<Location> {
|
||||
* Holds if `va` is an access to a value that is guarded by `instanceof t` or `case e t`.
|
||||
*/
|
||||
private predicate typeTestGuarded(VarAccess va, RefType t) {
|
||||
exists(Guard typeTest, BaseSsaVariable v |
|
||||
typeTest.appliesTypeTest(v.getAUse(), t, _) and
|
||||
va = v.getAUse() and
|
||||
exists(Guard typeTest, Base::SsaDefinition v |
|
||||
typeTest.appliesTypeTest(v.getARead(), t, _) and
|
||||
va = v.getARead() and
|
||||
guardControls_v1(typeTest, va.getBasicBlock(), true)
|
||||
)
|
||||
}
|
||||
@@ -274,12 +276,12 @@ private module Input implements TypeFlowInput<Location> {
|
||||
* Holds if `aa` is an access to a value that is guarded by `instanceof t` or `case e t`.
|
||||
*/
|
||||
private predicate arrayTypeTestGuarded(ArrayAccess aa, RefType t) {
|
||||
exists(Guard typeTest, BaseSsaVariable v1, BaseSsaVariable v2, ArrayAccess aa1 |
|
||||
exists(Guard typeTest, Base::SsaDefinition v1, Base::SsaDefinition v2, ArrayAccess aa1 |
|
||||
typeTest.appliesTypeTest(aa1, t, _) and
|
||||
aa1.getArray() = v1.getAUse() and
|
||||
aa1.getIndexExpr() = v2.getAUse() and
|
||||
aa.getArray() = v1.getAUse() and
|
||||
aa.getIndexExpr() = v2.getAUse() and
|
||||
aa1.getArray() = v1.getARead() and
|
||||
aa1.getIndexExpr() = v2.getARead() and
|
||||
aa.getArray() = v1.getARead() and
|
||||
aa.getIndexExpr() = v2.getARead() and
|
||||
guardControls_v1(typeTest, aa.getBasicBlock(), true)
|
||||
)
|
||||
}
|
||||
@@ -321,14 +323,14 @@ private module Input implements TypeFlowInput<Location> {
|
||||
* Holds if `ioe` checks `v`, its true-successor is `bb`, and `bb` has multiple
|
||||
* predecessors.
|
||||
*/
|
||||
private predicate instanceofDisjunct(InstanceOfExpr ioe, BasicBlock bb, BaseSsaVariable v) {
|
||||
ioe.getExpr() = v.getAUse() and
|
||||
private predicate instanceofDisjunct(InstanceOfExpr ioe, BasicBlock bb, Base::SsaDefinition v) {
|
||||
ioe.getExpr() = v.getARead() and
|
||||
strictcount(bb.getAPredecessor()) > 1 and
|
||||
exists(ConditionBlock cb | cb.getCondition() = ioe and cb.getTestSuccessor(true) = bb)
|
||||
}
|
||||
|
||||
/** Holds if `bb` is disjunctively guarded by multiple `instanceof` tests on `v`. */
|
||||
private predicate instanceofDisjunction(BasicBlock bb, BaseSsaVariable v) {
|
||||
private predicate instanceofDisjunction(BasicBlock bb, Base::SsaDefinition v) {
|
||||
strictcount(InstanceOfExpr ioe | instanceofDisjunct(ioe, bb, v)) =
|
||||
strictcount(bb.getAPredecessor())
|
||||
}
|
||||
@@ -338,10 +340,10 @@ private module Input implements TypeFlowInput<Location> {
|
||||
* `instanceof t_i` where `t` is one of those `t_i`.
|
||||
*/
|
||||
predicate instanceofDisjunctionGuarded(TypeFlowNode n, RefType t) {
|
||||
exists(BasicBlock bb, InstanceOfExpr ioe, BaseSsaVariable v, VarAccess va |
|
||||
exists(BasicBlock bb, InstanceOfExpr ioe, Base::SsaDefinition v, VarAccess va |
|
||||
instanceofDisjunction(bb, v) and
|
||||
bb.dominates(va.getBasicBlock()) and
|
||||
va = v.getAUse() and
|
||||
va = v.getARead() and
|
||||
instanceofDisjunct(ioe, bb, v) and
|
||||
t = ioe.getSyntacticCheckedType() and
|
||||
n.asExpr() = va
|
||||
|
||||
@@ -25,7 +25,8 @@ private module BaseSsaStage {
|
||||
predicate backref() {
|
||||
(exists(TLocalVar(_, _)) implies any()) and
|
||||
(exists(any(BaseSsaSourceVariable v).getAnAccess()) implies any()) and
|
||||
(exists(getAUse(_)) implies any())
|
||||
(exists(any(SsaDefinition def).getARead()) implies any()) and
|
||||
(captures(_, _) implies any())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +158,7 @@ private module BaseSsaImpl {
|
||||
|
||||
private import BaseSsaImpl
|
||||
|
||||
private module SsaInput implements SsaImplCommon::InputSig<Location, BasicBlock> {
|
||||
private module SsaImplInput implements SsaImplCommon::InputSig<Location, BasicBlock> {
|
||||
class SourceVariable = BaseSsaSourceVariable;
|
||||
|
||||
/**
|
||||
@@ -169,7 +170,7 @@ private module SsaInput implements SsaImplCommon::InputSig<Location, BasicBlock>
|
||||
certain = true
|
||||
or
|
||||
hasEntryDef(v, bb) and
|
||||
i = 0 and
|
||||
i = -1 and
|
||||
certain = true
|
||||
}
|
||||
|
||||
@@ -189,67 +190,46 @@ private module SsaInput implements SsaImplCommon::InputSig<Location, BasicBlock>
|
||||
}
|
||||
}
|
||||
|
||||
private module Impl = SsaImplCommon::Make<Location, Cfg, SsaInput>;
|
||||
private module Impl = SsaImplCommon::Make<Location, Cfg, SsaImplInput>;
|
||||
|
||||
private module SsaInput implements Impl::SsaInputSig {
|
||||
private import java as J
|
||||
|
||||
class Expr = J::Expr;
|
||||
|
||||
class Parameter = J::Parameter;
|
||||
|
||||
class VariableWrite = J::VariableWrite;
|
||||
|
||||
predicate explicitWrite(VariableWrite w, BasicBlock bb, int i, BaseSsaSourceVariable v) {
|
||||
variableUpdate(v, w.asExpr().getControlFlowNode(), bb, i)
|
||||
or
|
||||
exists(Parameter p, Callable c |
|
||||
c = p.getCallable() and
|
||||
v = TLocalVar(c, p) and
|
||||
w.isParameterInit(p) and
|
||||
c.getBody().getBasicBlock() = bb and
|
||||
i = -1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module Ssa = Impl::MakeSsa<SsaInput>;
|
||||
|
||||
import Ssa
|
||||
private import Cached
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
cached
|
||||
VarRead getAUse(Impl::Definition def) {
|
||||
BaseSsaStage::ref() and
|
||||
exists(BaseSsaSourceVariable v, BasicBlock bb, int i |
|
||||
Impl::ssaDefReachesRead(v, def, bb, i) and
|
||||
result.getControlFlowNode() = bb.getNode(i) and
|
||||
result = v.getAnAccess()
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate ssaDefReachesEndOfBlock(BasicBlock bb, Impl::Definition def) {
|
||||
Impl::ssaDefReachesEndOfBlock(bb, def, _)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate firstUse(Impl::Definition def, VarRead use) {
|
||||
exists(BasicBlock bb, int i |
|
||||
Impl::firstUse(def, bb, i, _) and
|
||||
use.getControlFlowNode() = bb.getNode(i)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate ssaUpdate(Impl::Definition def, VariableUpdate upd) {
|
||||
exists(BaseSsaSourceVariable v, BasicBlock bb, int i |
|
||||
def.definesAt(v, bb, i) and
|
||||
variableUpdate(v, upd.getControlFlowNode(), bb, i) and
|
||||
getDestVar(upd) = v
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate ssaImplicitInit(Impl::WriteDefinition def) {
|
||||
exists(BaseSsaSourceVariable v, BasicBlock bb, int i |
|
||||
def.definesAt(v, bb, i) and
|
||||
hasEntryDef(v, bb) and
|
||||
i = 0
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `init` is a closure variable that captures the value of `capturedvar`. */
|
||||
cached
|
||||
predicate captures(BaseSsaImplicitInit init, BaseSsaVariable capturedvar) {
|
||||
predicate captures(SsaImplicitEntryDefinition init, SsaDefinition capturedvar) {
|
||||
exists(BasicBlock bb, int i |
|
||||
Impl::ssaDefReachesRead(_, capturedvar, bb, i) and
|
||||
Ssa::ssaDefReachesUncertainRead(_, capturedvar, bb, i) and
|
||||
variableCapture(capturedvar.getSourceVariable(), init.getSourceVariable(), bb, i)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate phiHasInputFromBlock(Impl::PhiNode phi, Impl::Definition inp, BasicBlock bb) {
|
||||
Impl::phiHasInputFromBlock(phi, inp, bb)
|
||||
}
|
||||
|
||||
cached
|
||||
module SsaPublic {
|
||||
/**
|
||||
@@ -285,36 +265,73 @@ private module Cached {
|
||||
|
||||
import SsaPublic
|
||||
|
||||
/**
|
||||
* An SSA variable.
|
||||
*/
|
||||
class BaseSsaVariable extends Impl::Definition {
|
||||
/** Gets the `ControlFlowNode` at which this SSA variable is defined. */
|
||||
ControlFlowNode getCfgNode() {
|
||||
exists(BasicBlock bb, int i | this.definesAt(_, bb, i) and result = bb.getNode(0.maximum(i)))
|
||||
}
|
||||
/** An SSA definition in a closure that captures a variable. */
|
||||
class SsaCapturedDefinition extends SsaImplicitEntryDefinition {
|
||||
SsaCapturedDefinition() { captures(this, _) }
|
||||
|
||||
/** Gets an access of this SSA variable. */
|
||||
VarRead getAUse() { result = getAUse(this) }
|
||||
override string toString() { result = "SSA capture def(" + this.getSourceVariable() + ")" }
|
||||
|
||||
/** Holds if this definition captures the value of `capturedvar`. */
|
||||
predicate captures(SsaDefinition capturedvar) { captures(this, capturedvar) }
|
||||
|
||||
/**
|
||||
* Gets an access of the SSA source variable underlying this SSA variable
|
||||
* that can be reached from this SSA variable without passing through any
|
||||
* other uses, but potentially through phi nodes.
|
||||
*
|
||||
* Subsequent uses can be found by following the steps defined by
|
||||
* `baseSsaAdjacentUseUse`.
|
||||
* Gets a definition that ultimately defines the captured variable and is not itself a phi node.
|
||||
*/
|
||||
VarRead getAFirstUse() { firstUse(this, result) }
|
||||
SsaDefinition getAnUltimateCapturedDefinition() {
|
||||
exists(SsaDefinition capturedvar |
|
||||
captures(this, capturedvar) and result = capturedvar.getAnUltimateDefinition()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
deprecated private predicate ssaUpdate(Impl::Definition def, VariableUpdate upd) {
|
||||
exists(BaseSsaSourceVariable v, BasicBlock bb, int i |
|
||||
def.definesAt(v, bb, i) and
|
||||
variableUpdate(v, upd.getControlFlowNode(), bb, i) and
|
||||
getDestVar(upd) = v
|
||||
)
|
||||
}
|
||||
|
||||
deprecated private predicate ssaImplicitInit(Impl::WriteDefinition def) {
|
||||
exists(BaseSsaSourceVariable v, BasicBlock bb, int i |
|
||||
def.definesAt(v, bb, i) and
|
||||
hasEntryDef(v, bb) and
|
||||
i = -1
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `SsaDefinition` instead.
|
||||
*
|
||||
* An SSA variable.
|
||||
*/
|
||||
deprecated class BaseSsaVariable extends Impl::Definition {
|
||||
/**
|
||||
* DEPRECATED: Use `getControlFlowNode()` instead.
|
||||
*
|
||||
* Gets the `ControlFlowNode` at which this SSA variable is defined.
|
||||
*/
|
||||
deprecated ControlFlowNode getCfgNode() { result = this.(SsaDefinition).getControlFlowNode() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getARead()` instead.
|
||||
*
|
||||
* Gets an access of this SSA variable.
|
||||
*/
|
||||
deprecated VarRead getAUse() { result = this.(SsaDefinition).getARead() }
|
||||
|
||||
/** Holds if this SSA variable is live at the end of `b`. */
|
||||
predicate isLiveAtEndOfBlock(BasicBlock b) { ssaDefReachesEndOfBlock(b, this) }
|
||||
predicate isLiveAtEndOfBlock(BasicBlock b) { this.(SsaDefinition).isLiveAtEndOfBlock(b) }
|
||||
|
||||
/** Gets an input to the phi node defining the SSA variable. */
|
||||
private BaseSsaVariable getAPhiInput() { result = this.(BaseSsaPhiNode).getAPhiInput() }
|
||||
private BaseSsaVariable getAPhiInput() { result = this.(BaseSsaPhiNode).getAnInput() }
|
||||
|
||||
/** Gets a definition in the same callable that ultimately defines this variable and is not itself a phi node. */
|
||||
BaseSsaVariable getAnUltimateLocalDefinition() {
|
||||
/**
|
||||
* DEPRECATED: Use `SsaDefinition::getAnUltimateDefinition()` instead.
|
||||
*
|
||||
* Gets a definition in the same callable that ultimately defines this variable and is not itself a phi node.
|
||||
*/
|
||||
deprecated BaseSsaVariable getAnUltimateLocalDefinition() {
|
||||
result = this.getAPhiInput*() and not result instanceof BaseSsaPhiNode
|
||||
}
|
||||
|
||||
@@ -324,18 +341,27 @@ class BaseSsaVariable extends Impl::Definition {
|
||||
* variable.
|
||||
*/
|
||||
private BaseSsaVariable getAPhiInputOrCapturedVar() {
|
||||
result = this.(BaseSsaPhiNode).getAPhiInput() or
|
||||
result = this.(BaseSsaPhiNode).getAnInput() or
|
||||
this.(BaseSsaImplicitInit).captures(result)
|
||||
}
|
||||
|
||||
/** Gets a definition that ultimately defines this variable and is not itself a phi node. */
|
||||
BaseSsaVariable getAnUltimateDefinition() {
|
||||
/**
|
||||
* DEPRECATED: Use `SsaCapturedDefinition::getAnUltimateCapturedDefinition()`
|
||||
* and/or `SsaDefinition::getAnUltimateDefinition()` instead.
|
||||
*
|
||||
* Gets a definition that ultimately defines this variable and is not itself a phi node.
|
||||
*/
|
||||
deprecated BaseSsaVariable getAnUltimateDefinition() {
|
||||
result = this.getAPhiInputOrCapturedVar*() and not result instanceof BaseSsaPhiNode
|
||||
}
|
||||
}
|
||||
|
||||
/** An SSA variable that is defined by a `VariableUpdate`. */
|
||||
class BaseSsaUpdate extends BaseSsaVariable instanceof Impl::WriteDefinition {
|
||||
/**
|
||||
* DEPRECATED: Use `SsaExplicitWrite` instead.
|
||||
*
|
||||
* An SSA variable that is defined by a `VariableUpdate`.
|
||||
*/
|
||||
deprecated class BaseSsaUpdate extends BaseSsaVariable instanceof Impl::WriteDefinition {
|
||||
BaseSsaUpdate() { ssaUpdate(this, _) }
|
||||
|
||||
/** Gets the `VariableUpdate` defining the SSA variable. */
|
||||
@@ -343,34 +369,46 @@ class BaseSsaUpdate extends BaseSsaVariable instanceof Impl::WriteDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `SsaParameterInit` or `SsaCapturedDefinition` instead.
|
||||
*
|
||||
* An SSA variable that is defined by its initial value in the callable. This
|
||||
* includes initial values of parameters, fields, and closure variables.
|
||||
*/
|
||||
class BaseSsaImplicitInit extends BaseSsaVariable instanceof Impl::WriteDefinition {
|
||||
deprecated class BaseSsaImplicitInit extends BaseSsaVariable instanceof Impl::WriteDefinition {
|
||||
BaseSsaImplicitInit() { ssaImplicitInit(this) }
|
||||
|
||||
/** Holds if this is a closure variable that captures the value of `capturedvar`. */
|
||||
predicate captures(BaseSsaVariable capturedvar) { captures(this, capturedvar) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `SsaParameterInit::getParameter()` instead.
|
||||
*
|
||||
* Holds if the SSA variable is a parameter defined by its initial value in the callable.
|
||||
*/
|
||||
predicate isParameterDefinition(Parameter p) {
|
||||
deprecated predicate isParameterDefinition(Parameter p) {
|
||||
this.getSourceVariable() = TLocalVar(p.getCallable(), p) and
|
||||
p.getCallable().getBody().getControlFlowNode() = this.getCfgNode()
|
||||
}
|
||||
}
|
||||
|
||||
/** An SSA phi node. */
|
||||
class BaseSsaPhiNode extends BaseSsaVariable instanceof Impl::PhiNode {
|
||||
/** Gets an input to the phi node defining the SSA variable. */
|
||||
BaseSsaVariable getAPhiInput() { this.hasInputFromBlock(result, _) }
|
||||
/**
|
||||
* DEPRECATED: Use `SsaPhiDefinition` instead.
|
||||
*
|
||||
* An SSA phi node.
|
||||
*/
|
||||
deprecated class BaseSsaPhiNode extends BaseSsaVariable instanceof Impl::PhiNode {
|
||||
/**
|
||||
* DEPRECATED: Use `getAnInput()` instead.
|
||||
*
|
||||
* Gets an input to the phi node defining the SSA variable.
|
||||
*/
|
||||
deprecated BaseSsaVariable getAPhiInput() { this.hasInputFromBlock(result, _) }
|
||||
|
||||
/** Gets an input to the phi node defining the SSA variable. */
|
||||
BaseSsaVariable getAnInput() { this.hasInputFromBlock(result, _) }
|
||||
|
||||
/** Holds if `inp` is an input to the phi node along the edge originating in `bb`. */
|
||||
predicate hasInputFromBlock(BaseSsaVariable inp, BasicBlock bb) {
|
||||
phiHasInputFromBlock(this, inp, bb)
|
||||
this.(SsaPhiDefinition).hasInputFromBlock(inp, bb)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,12 +460,12 @@ predicate arrayStoreStep(Node node1, Node node2) {
|
||||
}
|
||||
|
||||
private predicate enhancedForStmtStep(Node node1, Node node2, Type containerType) {
|
||||
exists(EnhancedForStmt for, Expr e, SsaExplicitUpdate v |
|
||||
exists(EnhancedForStmt for, Expr e, SsaExplicitWrite v |
|
||||
for.getExpr() = e and
|
||||
node1.asExpr() = e and
|
||||
containerType = e.getType() and
|
||||
v.getDefiningExpr() = for.getVariable() and
|
||||
v.getAFirstUse() = node2.asExpr()
|
||||
ssaGetAFirstUse(v) = node2.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ private predicate deadcode(Expr e) {
|
||||
module SsaFlow {
|
||||
module Impl = SsaImpl::DataFlowIntegration;
|
||||
|
||||
private predicate ssaDefAssigns(SsaExplicitUpdate def, Expr value) {
|
||||
private predicate ssaDefAssigns(SsaExplicitWrite def, Expr value) {
|
||||
exists(VariableUpdate upd | upd = def.getDefiningExpr() |
|
||||
value = upd.(VariableAssign).getSource() or
|
||||
value = upd.(AssignOp) or
|
||||
@@ -46,7 +46,7 @@ module SsaFlow {
|
||||
or
|
||||
exists(Parameter p |
|
||||
n = TExplicitParameterNode(p) and
|
||||
result.(Impl::WriteDefSourceNode).getDefinition().(SsaImplicitInit).isParameterDefinition(p)
|
||||
result.(Impl::WriteDefSourceNode).getDefinition().(SsaParameterInit).getParameter() = p
|
||||
)
|
||||
or
|
||||
ssaDefAssigns(result.(Impl::WriteDefSourceNode).getDefinition(), n.asExpr())
|
||||
|
||||
@@ -62,10 +62,10 @@ private predicate fieldStep(Node node1, Node node2) {
|
||||
private predicate closureFlowStep(Expr e1, Expr e2) {
|
||||
simpleAstFlowStep(e1, e2)
|
||||
or
|
||||
exists(SsaVariable v |
|
||||
v.getAUse() = e2 and
|
||||
v.getAnUltimateDefinition().(SsaExplicitUpdate).getDefiningExpr().(VariableAssign).getSource() =
|
||||
e1
|
||||
exists(SsaDefinition v, SsaExplicitWrite def | v.getARead() = e2 and def.getValue() = e1 |
|
||||
v.getAnUltimateDefinition() = def
|
||||
or
|
||||
v.(SsaCapturedDefinition).getAnUltimateCapturedDefinition() = def
|
||||
)
|
||||
}
|
||||
|
||||
@@ -395,13 +395,13 @@ class CastNode extends ExprNode {
|
||||
CastNode() {
|
||||
this.getExpr() instanceof CastingExpr
|
||||
or
|
||||
exists(SsaExplicitUpdate upd |
|
||||
exists(SsaExplicitWrite upd |
|
||||
upd.getDefiningExpr().(VariableAssign).getSource() =
|
||||
[
|
||||
any(SwitchStmt ss).getExpr(), any(SwitchExpr se).getExpr(),
|
||||
any(InstanceOfExpr ioe).getExpr()
|
||||
] and
|
||||
this.asExpr() = upd.getAFirstUse()
|
||||
this.asExpr() = ssaGetAFirstUse(upd)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -531,9 +531,9 @@ class NodeRegion instanceof BasicBlock {
|
||||
private predicate constantBooleanExpr(Expr e, boolean val) {
|
||||
e.(CompileTimeConstantExpr).getBooleanValue() = val
|
||||
or
|
||||
exists(SsaExplicitUpdate v, Expr src |
|
||||
e = v.getAUse() and
|
||||
src = v.getDefiningExpr().(VariableAssign).getSource() and
|
||||
exists(SsaExplicitWrite v, Expr src |
|
||||
e = v.getARead() and
|
||||
src = v.getValue() and
|
||||
constantBooleanExpr(src, val)
|
||||
)
|
||||
}
|
||||
@@ -551,15 +551,15 @@ private class ConstantBooleanArgumentNode extends ArgumentNode, ExprNode {
|
||||
*/
|
||||
predicate isUnreachableInCall(NodeRegion nr, DataFlowCall call) {
|
||||
exists(
|
||||
ExplicitParameterNode paramNode, ConstantBooleanArgumentNode arg, SsaImplicitInit param,
|
||||
ExplicitParameterNode paramNode, ConstantBooleanArgumentNode arg, SsaParameterInit param,
|
||||
Guard guard
|
||||
|
|
||||
// get constant bool argument and parameter for this call
|
||||
viableParamArg(call, pragma[only_bind_into](paramNode), arg) and
|
||||
// get the ssa variable definition for this parameter
|
||||
param.isParameterDefinition(paramNode.getParameter()) and
|
||||
param.getParameter() = paramNode.getParameter() and
|
||||
// which is used in a guard
|
||||
param.getAUse() = guard and
|
||||
param.getARead() = guard and
|
||||
// which controls `n` with the opposite value of `arg`
|
||||
guard
|
||||
.controls(nr,
|
||||
|
||||
@@ -99,11 +99,12 @@ predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)
|
||||
* updates.
|
||||
*/
|
||||
predicate hasNonlocalValue(FieldRead fr) {
|
||||
not exists(SsaVariable v | v.getAUse() = fr)
|
||||
not exists(SsaDefinition v | v.getARead() = fr)
|
||||
or
|
||||
exists(SsaVariable v, SsaVariable def | v.getAUse() = fr and def = v.getAnUltimateDefinition() |
|
||||
def instanceof SsaImplicitInit or
|
||||
def instanceof SsaImplicitUpdate
|
||||
exists(SsaDefinition v, SsaDefinition def |
|
||||
v.getARead() = fr and
|
||||
def = v.getAnUltimateDefinition() and
|
||||
def instanceof SsaImplicitWrite
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -82,13 +82,6 @@ private module TrackedVariablesImpl {
|
||||
|
||||
private import TrackedVariablesImpl
|
||||
|
||||
private predicate untrackedFieldWrite(BasicBlock bb, int i, SsaSourceVariable v) {
|
||||
v =
|
||||
any(SsaSourceField nf |
|
||||
bb.getNode(i + 1) = nf.getAnAccess().(FieldRead).getControlFlowNode() and not trackField(nf)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the definition point of a nested class in the parent scope. */
|
||||
private ControlFlowNode parentDef(NestedClass nc) {
|
||||
nc.(AnonymousClass).getClassInstanceExpr().getControlFlowNode() = result or
|
||||
@@ -171,7 +164,7 @@ private predicate uncertainVariableUpdateImpl(TrackedVar v, ControlFlowNode n, B
|
||||
predicate uncertainVariableUpdate(TrackedVar v, ControlFlowNode n, BasicBlock b, int i) =
|
||||
forceLocal(uncertainVariableUpdateImpl/4)(v, n, b, i)
|
||||
|
||||
private module SsaInput implements SsaImplCommon::InputSig<Location, BasicBlock> {
|
||||
private module SsaImplInput implements SsaImplCommon::InputSig<Location, BasicBlock> {
|
||||
class SourceVariable = SsaSourceVariable;
|
||||
|
||||
/**
|
||||
@@ -184,11 +177,8 @@ private module SsaInput implements SsaImplCommon::InputSig<Location, BasicBlock>
|
||||
certainVariableUpdate(v, _, bb, i) and
|
||||
certain = true
|
||||
or
|
||||
untrackedFieldWrite(bb, i, v) and
|
||||
certain = true
|
||||
or
|
||||
hasEntryDef(v, bb) and
|
||||
i = 0 and
|
||||
i = -1 and
|
||||
certain = true
|
||||
or
|
||||
uncertainVariableUpdate(v, _, bb, i) and
|
||||
@@ -204,7 +194,10 @@ private module SsaInput implements SsaImplCommon::InputSig<Location, BasicBlock>
|
||||
hasDominanceInformation(bb) and
|
||||
(
|
||||
exists(VarRead use |
|
||||
v.getAnAccess() = use and bb.getNode(i) = use.getControlFlowNode() and certain = true
|
||||
v instanceof TrackedVar and
|
||||
v.getAnAccess() = use and
|
||||
bb.getNode(i) = use.getControlFlowNode() and
|
||||
certain = true
|
||||
)
|
||||
or
|
||||
variableCapture(v, _, bb, i) and
|
||||
@@ -213,7 +206,35 @@ private module SsaInput implements SsaImplCommon::InputSig<Location, BasicBlock>
|
||||
}
|
||||
}
|
||||
|
||||
import SsaImplCommon::Make<Location, Cfg, SsaInput> as Impl
|
||||
import SsaImplCommon::Make<Location, Cfg, SsaImplInput> as Impl
|
||||
|
||||
private module SsaInput implements Impl::SsaInputSig {
|
||||
private import java as J
|
||||
|
||||
class Expr = J::Expr;
|
||||
|
||||
class Parameter = J::Parameter;
|
||||
|
||||
class VariableWrite = J::VariableWrite;
|
||||
|
||||
predicate explicitWrite(VariableWrite w, BasicBlock bb, int i, SsaSourceVariable v) {
|
||||
exists(VariableUpdate upd |
|
||||
upd = w.asExpr() and
|
||||
certainVariableUpdate(v, upd.getControlFlowNode(), bb, i) and
|
||||
getDestVar(upd) = v
|
||||
)
|
||||
or
|
||||
exists(Parameter p, Callable c |
|
||||
c = p.getCallable() and
|
||||
v = TLocalVar(c, p) and
|
||||
w.isParameterInit(p) and
|
||||
c.getBody().getBasicBlock() = bb and
|
||||
i = -1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module Ssa = Impl::MakeSsa<SsaInput>;
|
||||
|
||||
final class Definition = Impl::Definition;
|
||||
|
||||
@@ -223,14 +244,51 @@ final class UncertainWriteDefinition = Impl::UncertainWriteDefinition;
|
||||
|
||||
final class PhiNode = Impl::PhiNode;
|
||||
|
||||
class UntrackedDef extends Definition {
|
||||
private VarRead read;
|
||||
predicate ssaExplicitUpdate(SsaUpdate def, VariableUpdate upd) {
|
||||
exists(SsaSourceVariable v, BasicBlock bb, int i |
|
||||
def.definesAt(v, bb, i) and
|
||||
certainVariableUpdate(v, upd.getControlFlowNode(), bb, i) and
|
||||
getDestVar(upd) = def.getSourceVariable()
|
||||
)
|
||||
}
|
||||
|
||||
UntrackedDef() { ssaUntrackedDef(this, read) }
|
||||
deprecated predicate ssaUncertainImplicitUpdate(SsaImplicitUpdate def) {
|
||||
exists(SsaSourceVariable v, BasicBlock bb, int i |
|
||||
def.definesAt(v, bb, i) and
|
||||
uncertainVariableUpdate(v, _, bb, i)
|
||||
)
|
||||
}
|
||||
|
||||
string toString() { result = read.toString() }
|
||||
predicate ssaImplicitInit(WriteDefinition def) {
|
||||
exists(SsaSourceVariable v, BasicBlock bb, int i |
|
||||
def.definesAt(v, bb, i) and
|
||||
hasEntryDef(v, bb) and
|
||||
i = -1
|
||||
)
|
||||
}
|
||||
|
||||
Location getLocation() { result = read.getLocation() }
|
||||
/**
|
||||
* Holds if the SSA definition of `v` at `def` reaches `redef` without crossing another
|
||||
* SSA definition of `v`.
|
||||
*/
|
||||
deprecated predicate ssaDefReachesUncertainDef(TrackedSsaDef def, SsaUncertainImplicitUpdate redef) {
|
||||
Impl::uncertainWriteDefinitionInput(redef, def)
|
||||
}
|
||||
|
||||
VarRead getAUse(Definition def) {
|
||||
exists(SsaSourceVariable v, BasicBlock bb, int i |
|
||||
Impl::ssaDefReachesRead(v, def, bb, i) and
|
||||
result.getControlFlowNode() = bb.getNode(i) and
|
||||
result = v.getAnAccess()
|
||||
)
|
||||
}
|
||||
|
||||
predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def) {
|
||||
Impl::ssaDefReachesEndOfBlock(bb, def, _)
|
||||
}
|
||||
|
||||
deprecated predicate phiHasInputFromBlock(PhiNode phi, Definition inp, BasicBlock bb) {
|
||||
Impl::phiHasInputFromBlock(phi, inp, bb)
|
||||
}
|
||||
|
||||
cached
|
||||
@@ -247,24 +305,6 @@ private module Cached {
|
||||
result.getAnAccess() = upd.(UnaryAssignExpr).getExpr()
|
||||
}
|
||||
|
||||
cached
|
||||
predicate ssaExplicitUpdate(SsaUpdate def, VariableUpdate upd) {
|
||||
exists(SsaSourceVariable v, BasicBlock bb, int i |
|
||||
def.definesAt(v, bb, i) and
|
||||
certainVariableUpdate(v, upd.getControlFlowNode(), bb, i) and
|
||||
getDestVar(upd) = def.getSourceVariable()
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate ssaUntrackedDef(Definition def, VarRead read) {
|
||||
exists(SsaSourceVariable v, BasicBlock bb, int i |
|
||||
def.definesAt(v, bb, i) and
|
||||
untrackedFieldWrite(bb, i, v) and
|
||||
read.getControlFlowNode() = bb.getNode(i + 1)
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
* The SSA construction for a field `f` relies on implicit update nodes at
|
||||
* every call site that conceivably could reach an update of the field.
|
||||
@@ -484,46 +524,20 @@ private module Cached {
|
||||
|
||||
overlay[global]
|
||||
cached
|
||||
predicate defUpdatesNamedField(SsaImplicitUpdate def, TrackedField f, Callable setter) {
|
||||
f = def.getSourceVariable() and
|
||||
updatesNamedField0(def.getCfgNode().asCall(), f, setter)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate ssaUncertainImplicitUpdate(SsaImplicitUpdate def) {
|
||||
exists(SsaSourceVariable v, BasicBlock bb, int i |
|
||||
def.definesAt(v, bb, i) and
|
||||
uncertainVariableUpdate(v, _, bb, i)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate ssaImplicitInit(WriteDefinition def) {
|
||||
exists(SsaSourceVariable v, BasicBlock bb, int i |
|
||||
def.definesAt(v, bb, i) and
|
||||
hasEntryDef(v, bb) and
|
||||
i = 0
|
||||
)
|
||||
predicate defUpdatesNamedField(SsaImplicitWrite calldef, TrackedField f, Callable setter) {
|
||||
f = calldef.getSourceVariable() and
|
||||
updatesNamedField0(calldef.getControlFlowNode().asCall(), f, setter)
|
||||
}
|
||||
|
||||
/** Holds if `init` is a closure variable that captures the value of `capturedvar`. */
|
||||
cached
|
||||
predicate captures(SsaImplicitInit init, SsaVariable capturedvar) {
|
||||
predicate captures(SsaImplicitEntryDefinition init, SsaDefinition capturedvar) {
|
||||
exists(BasicBlock bb, int i |
|
||||
Impl::ssaDefReachesRead(_, capturedvar, bb, i) and
|
||||
Ssa::ssaDefReachesUncertainRead(_, capturedvar, bb, i) and
|
||||
variableCapture(capturedvar.getSourceVariable(), init.getSourceVariable(), bb, i)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the SSA definition of `v` at `def` reaches `redef` without crossing another
|
||||
* SSA definition of `v`.
|
||||
*/
|
||||
cached
|
||||
predicate ssaDefReachesUncertainDef(TrackedSsaDef def, SsaUncertainImplicitUpdate redef) {
|
||||
Impl::uncertainWriteDefinitionInput(redef, def)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the value defined at `def` can reach `use` without passing through
|
||||
* any other uses, but possibly through phi nodes and uncertain implicit updates.
|
||||
@@ -536,25 +550,6 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
VarRead getAUse(Definition def) {
|
||||
exists(SsaSourceVariable v, BasicBlock bb, int i |
|
||||
Impl::ssaDefReachesRead(v, def, bb, i) and
|
||||
result.getControlFlowNode() = bb.getNode(i) and
|
||||
result = v.getAnAccess()
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def) {
|
||||
Impl::ssaDefReachesEndOfBlock(bb, def, _)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate phiHasInputFromBlock(PhiNode phi, Definition inp, BasicBlock bb) {
|
||||
Impl::phiHasInputFromBlock(phi, inp, bb)
|
||||
}
|
||||
|
||||
cached
|
||||
module DataFlowIntegration {
|
||||
import DataFlowIntegrationImpl
|
||||
@@ -664,14 +659,12 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
|
||||
}
|
||||
}
|
||||
|
||||
Expr getARead(Definition def) { result = getAUse(def) }
|
||||
Expr getARead(Definition def) { result = def.(SsaDefinition).getARead() }
|
||||
|
||||
predicate ssaDefHasSource(WriteDefinition def) {
|
||||
def instanceof SsaExplicitUpdate or def.(SsaImplicitInit).isParameterDefinition(_)
|
||||
}
|
||||
predicate ssaDefHasSource(WriteDefinition def) { def instanceof SsaExplicitWrite }
|
||||
|
||||
predicate allowFlowIntoUncertainDef(UncertainWriteDefinition def) {
|
||||
def instanceof SsaUncertainImplicitUpdate
|
||||
def instanceof SsaUncertainWrite
|
||||
}
|
||||
|
||||
class GuardValue = Guards::GuardValue;
|
||||
|
||||
@@ -8,7 +8,9 @@ private import java as J
|
||||
private import semmle.code.java.dataflow.SSA as Ssa
|
||||
private import semmle.code.java.dataflow.RangeUtils as RU
|
||||
|
||||
class SsaVariable = Ssa::SsaVariable;
|
||||
class SsaVariable extends Ssa::SsaDefinition {
|
||||
Expr getAUse() { result = super.getARead() }
|
||||
}
|
||||
|
||||
class Expr = J::Expr;
|
||||
|
||||
|
||||
@@ -11,9 +11,11 @@ module Private {
|
||||
|
||||
class BasicBlock = BB::BasicBlock;
|
||||
|
||||
class SsaVariable = Ssa::SsaVariable;
|
||||
class SsaVariable extends Ssa::SsaDefinition {
|
||||
Expr getAUse() { result = super.getARead() }
|
||||
}
|
||||
|
||||
class SsaPhiNode = Ssa::SsaPhiNode;
|
||||
class SsaPhiNode = Ssa::SsaPhiDefinition;
|
||||
|
||||
class Expr = J::Expr;
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ module Private {
|
||||
|
||||
class Guard = G::Guards_v2::Guard;
|
||||
|
||||
class SsaVariable = Ssa::SsaVariable;
|
||||
class SsaVariable = Ssa::SsaDefinition;
|
||||
|
||||
class SsaPhiNode = Ssa::SsaPhiNode;
|
||||
class SsaPhiNode = Ssa::SsaPhiDefinition;
|
||||
|
||||
class VarAccess = J::VarAccess;
|
||||
|
||||
@@ -240,8 +240,8 @@ private module Impl {
|
||||
}
|
||||
|
||||
/** Returns the underlying variable update of the explicit SSA variable `v`. */
|
||||
VariableUpdate getExplicitSsaAssignment(SsaVariable v) {
|
||||
result = v.(SsaExplicitUpdate).getDefiningExpr()
|
||||
VariableUpdate getExplicitSsaAssignment(SsaDefinition v) {
|
||||
result = v.(SsaExplicitWrite).getDefiningExpr()
|
||||
}
|
||||
|
||||
/** Returns the assignment of the variable update `def`. */
|
||||
@@ -267,13 +267,12 @@ private module Impl {
|
||||
}
|
||||
|
||||
/** Gets the variable underlying the implicit SSA variable `v`. */
|
||||
Variable getImplicitSsaDeclaration(SsaVariable v) {
|
||||
result = v.(SsaImplicitUpdate).getSourceVariable().getVariable() or
|
||||
result = v.(SsaImplicitInit).getSourceVariable().getVariable()
|
||||
Variable getImplicitSsaDeclaration(SsaDefinition v) {
|
||||
result = v.(SsaImplicitWrite).getSourceVariable().getVariable()
|
||||
}
|
||||
|
||||
/** Holds if the variable underlying the implicit SSA variable `v` is not a field. */
|
||||
predicate nonFieldImplicitSsaDefinition(SsaImplicitInit v) { v.isParameterDefinition(_) }
|
||||
predicate nonFieldImplicitSsaDefinition(SsaParameterInit v) { any() }
|
||||
|
||||
/** Returned an expression that is assigned to `f`. */
|
||||
Expr getAssignedValueToField(Field f) {
|
||||
@@ -324,7 +323,7 @@ private module Impl {
|
||||
result = e.(CastingExpr).getExpr()
|
||||
}
|
||||
|
||||
Expr getARead(SsaVariable v) { result = v.getAUse() }
|
||||
Expr getARead(SsaDefinition v) { result = v.getARead() }
|
||||
|
||||
Field getField(FieldAccess fa) { result = fa.getField() }
|
||||
|
||||
|
||||
@@ -8,14 +8,14 @@ private import semmle.code.java.dataflow.SSA as Ssa
|
||||
private import semmle.code.java.controlflow.BasicBlocks as BB
|
||||
private import SsaReadPositionCommon
|
||||
|
||||
class SsaVariable = Ssa::SsaVariable;
|
||||
class SsaVariable = Ssa::SsaDefinition;
|
||||
|
||||
class SsaPhiNode = Ssa::SsaPhiNode;
|
||||
class SsaPhiNode = Ssa::SsaPhiDefinition;
|
||||
|
||||
class BasicBlock = BB::BasicBlock;
|
||||
|
||||
/** Gets a basic block in which SSA variable `v` is read. */
|
||||
BasicBlock getAReadBasicBlock(SsaVariable v) { result = v.getAUse().getBasicBlock() }
|
||||
BasicBlock getAReadBasicBlock(SsaVariable v) { result = v.getARead().getBasicBlock() }
|
||||
|
||||
private predicate id(BB::ExprParent x, BB::ExprParent y) { x = y }
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
import java
|
||||
private import VirtualDispatch
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA as Base
|
||||
private import semmle.code.java.dataflow.internal.DataFlowUtil as DataFlow
|
||||
private import semmle.code.java.dataflow.internal.DataFlowPrivate as DataFlowPrivate
|
||||
private import semmle.code.java.dataflow.InstanceAccess
|
||||
@@ -162,14 +162,28 @@ private module TypeTrackingSteps {
|
||||
storeContents = loadContents
|
||||
}
|
||||
|
||||
predicate simpleLocalSmallStep(Node n1, Node n2) {
|
||||
exists(BaseSsaVariable v, BaseSsaVariable def |
|
||||
def.(BaseSsaUpdate).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr()
|
||||
or
|
||||
def.(BaseSsaImplicitInit).isParameterDefinition(n1.asParameter())
|
||||
/**
|
||||
* Holds if `n` is a read of an SSA variable that is ultimately defined by `def`.
|
||||
*
|
||||
* This includes reads of captured variables even though they are not technically
|
||||
* local steps, but treating them as local is useful for type tracking purposes.
|
||||
*/
|
||||
private predicate readsSsa(Node n, Base::SsaDefinition def) {
|
||||
exists(Base::SsaDefinition v |
|
||||
v.getAnUltimateDefinition() = def or
|
||||
v.(Base::SsaCapturedDefinition).getAnUltimateCapturedDefinition() = def
|
||||
|
|
||||
v.getAnUltimateDefinition() = def and
|
||||
v.getAUse() = n2.asExpr()
|
||||
v.getARead() = n.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
predicate simpleLocalSmallStep(Node n1, Node n2) {
|
||||
exists(Base::SsaDefinition def |
|
||||
def.(Base::SsaExplicitWrite).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr()
|
||||
or
|
||||
def.(Base::SsaParameterInit).getParameter() = n1.asParameter()
|
||||
|
|
||||
readsSsa(n2, def)
|
||||
)
|
||||
or
|
||||
exists(Callable c | n1.(DataFlow::InstanceParameterNode).getCallable() = c |
|
||||
@@ -220,11 +234,10 @@ private module TypeTrackingSteps {
|
||||
n2.asExpr() = get
|
||||
)
|
||||
or
|
||||
exists(EnhancedForStmt for, BaseSsaVariable ssa, BaseSsaVariable def |
|
||||
for.getVariable() = def.(BaseSsaUpdate).getDefiningExpr() and
|
||||
exists(EnhancedForStmt for, Base::SsaDefinition def |
|
||||
for.getVariable() = def.(Base::SsaExplicitWrite).getDefiningExpr() and
|
||||
for.getExpr() = v.getAnAccess() and
|
||||
ssa.getAnUltimateDefinition() = def and
|
||||
ssa.getAUse() = n2.asExpr()
|
||||
readsSsa(n2, def)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -259,16 +272,15 @@ private module TypeTrackingSteps {
|
||||
}
|
||||
|
||||
predicate loadStep(Node n1, LocalSourceNode n2, Content f) {
|
||||
exists(BaseSsaVariable v, BaseSsaVariable def |
|
||||
exists(Base::SsaDefinition def |
|
||||
exists(EnhancedForStmt for |
|
||||
for.getVariable() = def.(BaseSsaUpdate).getDefiningExpr() and
|
||||
for.getVariable() = def.(Base::SsaExplicitWrite).getDefiningExpr() and
|
||||
for.getExpr() = n1.asExpr() and
|
||||
n1.getType() instanceof Array and
|
||||
f = ContentArray()
|
||||
)
|
||||
|
|
||||
v.getAnUltimateDefinition() = def and
|
||||
v.getAUse() = n2.asExpr()
|
||||
readsSsa(n2, def)
|
||||
)
|
||||
or
|
||||
n2.asExpr().(ArrayAccess).getArray() = n1.asExpr()
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
import java
|
||||
private import VirtualDispatch
|
||||
private import semmle.code.java.controlflow.Guards
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA as Base
|
||||
private import semmle.code.java.dataflow.internal.DataFlowUtil
|
||||
private import semmle.code.java.dataflow.internal.DataFlowPrivate
|
||||
private import semmle.code.java.dataflow.internal.ContainerFlow
|
||||
@@ -71,21 +71,24 @@ private predicate callFlowStep(Node n1, Node n2) {
|
||||
* flow, calls, returns, fields, array reads or writes, or container taint steps.
|
||||
*/
|
||||
private predicate step(Node n1, Node n2) {
|
||||
exists(BaseSsaVariable v, BaseSsaVariable def |
|
||||
def.(BaseSsaUpdate).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr()
|
||||
exists(Base::SsaDefinition v, Base::SsaDefinition def |
|
||||
def.(Base::SsaExplicitWrite).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr()
|
||||
or
|
||||
def.(BaseSsaImplicitInit).isParameterDefinition(n1.asParameter())
|
||||
def.(Base::SsaParameterInit).getParameter() = n1.asParameter()
|
||||
or
|
||||
exists(EnhancedForStmt for |
|
||||
for.getVariable() = def.(BaseSsaUpdate).getDefiningExpr() and
|
||||
for.getVariable() = def.(Base::SsaExplicitWrite).getDefiningExpr() and
|
||||
for.getExpr() = n1.asExpr()
|
||||
)
|
||||
|
|
||||
v.getAnUltimateDefinition() = def and
|
||||
v.getAUse() = n2.asExpr()
|
||||
(
|
||||
v.(Base::SsaCapturedDefinition).getAnUltimateCapturedDefinition() = def or
|
||||
v.getAnUltimateDefinition() = def
|
||||
) and
|
||||
v.getARead() = n2.asExpr()
|
||||
)
|
||||
or
|
||||
baseSsaAdjacentUseUse(n1.asExpr(), n2.asExpr())
|
||||
Base::baseSsaAdjacentUseUse(n1.asExpr(), n2.asExpr())
|
||||
or
|
||||
exists(Callable c | n1.(InstanceParameterNode).getCallable() = c |
|
||||
exists(InstanceAccess ia |
|
||||
|
||||
@@ -7,7 +7,7 @@ import java
|
||||
import semmle.code.java.dataflow.TypeFlow
|
||||
private import DispatchFlow as DispatchFlow
|
||||
private import ObjFlow as ObjFlow
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA as Base
|
||||
private import semmle.code.java.controlflow.Guards
|
||||
private import semmle.code.java.dispatch.internal.Unification
|
||||
|
||||
@@ -194,10 +194,10 @@ private module Dispatch {
|
||||
*/
|
||||
private predicate impossibleDispatchTarget(MethodCall source, Method tgt) {
|
||||
tgt = viableImpl_v1_cand(source) and
|
||||
exists(Guard typeTest, BaseSsaVariable v, Expr q, RefType t |
|
||||
exists(Guard typeTest, Base::SsaDefinition v, Expr q, RefType t |
|
||||
source.getQualifier() = q and
|
||||
v.getAUse() = q and
|
||||
typeTest.appliesTypeTest(v.getAUse(), t, false) and
|
||||
v.getARead() = q and
|
||||
typeTest.appliesTypeTest(v.getARead(), t, false) and
|
||||
guardControls_v1(typeTest, q.getBasicBlock(), false) and
|
||||
tgt.getDeclaringType().getSourceDeclaration().getASourceSupertype*() = t.getErasure()
|
||||
)
|
||||
|
||||
@@ -41,11 +41,13 @@ private class InputStreamWrapperCapturedJumpStep extends AdditionalTaintStep {
|
||||
*/
|
||||
private class InputStreamWrapperCapturedLocalStep extends AdditionalTaintStep {
|
||||
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(InputStreamRead m, NestedClass wrapper, SsaVariable captured, SsaImplicitInit capturer |
|
||||
exists(
|
||||
InputStreamRead m, NestedClass wrapper, SsaDefinition captured, SsaCapturedDefinition capturer
|
||||
|
|
||||
wrapper.getASourceSupertype+() instanceof TypeInputStream and
|
||||
m.getDeclaringType() = wrapper and
|
||||
capturer.captures(captured) and
|
||||
TaintTracking::localTaint(DataFlow::exprNode(capturer.getAFirstUse()),
|
||||
TaintTracking::localTaint(DataFlow::exprNode(ssaGetAFirstUse(capturer)),
|
||||
any(DataFlow::PostUpdateNode pun |
|
||||
pun.getPreUpdateNode().asExpr() = m.getParameter(0).getAnAccess()
|
||||
)) and
|
||||
@@ -55,9 +57,9 @@ private class InputStreamWrapperCapturedLocalStep extends AdditionalTaintStep {
|
||||
.getASourceSupertype*()
|
||||
.getSourceDeclaration() = wrapper
|
||||
|
|
||||
n1.asExpr() = captured.(SsaExplicitUpdate).getDefiningExpr().(VariableAssign).getSource()
|
||||
n1.asExpr() = captured.(SsaExplicitWrite).getDefiningExpr().(VariableAssign).getSource()
|
||||
or
|
||||
captured.(SsaImplicitInit).isParameterDefinition(n1.asParameter())
|
||||
captured.(SsaParameterInit).getParameter() = n1.asParameter()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,10 +262,10 @@ private predicate reaches(Expr src, Argument arg) {
|
||||
any(StartComponentMethodCall ma).getIntentArg() = arg and
|
||||
src = arg
|
||||
or
|
||||
exists(Expr mid, BaseSsa::BaseSsaVariable ssa, BaseSsa::BaseSsaUpdate upd |
|
||||
exists(Expr mid, BaseSsa::SsaDefinition ssa, BaseSsa::SsaExplicitWrite upd |
|
||||
reaches(mid, arg) and
|
||||
mid = ssa.getAUse() and
|
||||
upd = ssa.getAnUltimateLocalDefinition() and
|
||||
mid = ssa.getARead() and
|
||||
upd = ssa.getAnUltimateDefinition() and
|
||||
src = upd.getDefiningExpr().(VariableAssign).getSource()
|
||||
)
|
||||
or
|
||||
|
||||
@@ -38,9 +38,13 @@ private predicate isShell(Expr ex) {
|
||||
cmd.regexpMatch(".*(sh|javac?|python[23]?|osascript|cmd)(\\.exe)?$")
|
||||
)
|
||||
or
|
||||
exists(SsaVariable ssa |
|
||||
ex = ssa.getAUse() and
|
||||
isShell(ssa.getAnUltimateDefinition().(SsaExplicitUpdate).getDefiningExpr())
|
||||
exists(SsaDefinition ssa, SsaExplicitWrite def |
|
||||
ex = ssa.getARead() and
|
||||
isShell(def.getDefiningExpr())
|
||||
|
|
||||
ssa.getAnUltimateDefinition() = def
|
||||
or
|
||||
ssa.(SsaCapturedDefinition).getAnUltimateCapturedDefinition() = def
|
||||
)
|
||||
or
|
||||
isShell(ex.(Assignment).getRhs())
|
||||
@@ -61,17 +65,17 @@ private class ListOfStringType extends CollectionType {
|
||||
/**
|
||||
* A variable that could be used as a list of arguments to a command.
|
||||
*/
|
||||
private class CommandArgumentList extends SsaExplicitUpdate {
|
||||
private class CommandArgumentList extends SsaExplicitWrite {
|
||||
CommandArgumentList() {
|
||||
this.getSourceVariable().getType() instanceof ListOfStringType and
|
||||
forex(CollectionMutation ma | ma.getQualifier() = this.getAUse() |
|
||||
forex(CollectionMutation ma | ma.getQualifier() = this.getARead() |
|
||||
ma.getMethod().getName().matches("add%")
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a use of the variable for which the list could be empty. */
|
||||
private VarRead getAUseBeforeFirstAdd() {
|
||||
result = this.getAFirstUse()
|
||||
result = ssaGetAFirstUse(this)
|
||||
or
|
||||
exists(VarRead mid |
|
||||
mid = this.getAUseBeforeFirstAdd() and
|
||||
@@ -87,7 +91,7 @@ private class CommandArgumentList extends SsaExplicitUpdate {
|
||||
* Gets an addition to this list, i.e. a call to an `add` or `addAll` method.
|
||||
*/
|
||||
MethodCall getAnAdd() {
|
||||
result.getQualifier() = this.getAUse() and
|
||||
result.getQualifier() = this.getARead() and
|
||||
result.getMethod().getName().matches("add%")
|
||||
}
|
||||
|
||||
@@ -121,10 +125,10 @@ private predicate arrayVarWrite(ArrayAccess acc) { exists(Assignment a | a.getDe
|
||||
/**
|
||||
* A variable that could be an array of arguments to a command.
|
||||
*/
|
||||
private class CommandArgumentArray extends SsaExplicitUpdate {
|
||||
private class CommandArgumentArray extends SsaExplicitWrite {
|
||||
CommandArgumentArray() {
|
||||
this.getSourceVariable().getType() instanceof ArrayOfStringType and
|
||||
forall(ArrayAccess a | a.getArray() = this.getAUse() and arrayVarWrite(a) |
|
||||
forall(ArrayAccess a | a.getArray() = this.getARead() and arrayVarWrite(a) |
|
||||
a.getIndexExpr() instanceof CompileTimeConstantExpr
|
||||
)
|
||||
}
|
||||
@@ -133,7 +137,7 @@ private class CommandArgumentArray extends SsaExplicitUpdate {
|
||||
Expr getAWrite(int index, VarRead use) {
|
||||
exists(Assignment a, ArrayAccess acc |
|
||||
acc.getArray() = use and
|
||||
use = this.getAUse() and
|
||||
use = this.getARead() and
|
||||
index = acc.getIndexExpr().(CompileTimeConstantExpr).getIntValue() and
|
||||
acc = a.getDest() and
|
||||
result = a.getRhs()
|
||||
@@ -150,7 +154,7 @@ private class CommandArgumentArray extends SsaExplicitUpdate {
|
||||
private class CommandArgArrayImmutableFirst extends CommandArgumentArray {
|
||||
CommandArgArrayImmutableFirst() {
|
||||
(exists(this.getAWrite(0)) or exists(firstElementOf(this.getDefiningExpr()))) and
|
||||
forall(VarRead use | exists(this.getAWrite(0, use)) | use = this.getAFirstUse())
|
||||
forall(VarRead use | exists(this.getAWrite(0, use)) | use = ssaGetAFirstUse(this))
|
||||
}
|
||||
|
||||
/** Gets the first element of this array. */
|
||||
@@ -173,7 +177,9 @@ private Expr firstElementOf(Expr arr) {
|
||||
or
|
||||
result = firstElementOf(arr.(LocalVariableDeclExpr).getInit())
|
||||
or
|
||||
exists(CommandArgArrayImmutableFirst caa | arr = caa.getAUse() | result = caa.getFirstElement())
|
||||
exists(CommandArgArrayImmutableFirst caa | arr = caa.getARead() |
|
||||
result = caa.getFirstElement()
|
||||
)
|
||||
or
|
||||
exists(MethodCall ma, Method m |
|
||||
arr = ma and
|
||||
|
||||
@@ -9,7 +9,7 @@ import java
|
||||
private import codeql.typeflow.UniversalFlow as UniversalFlow
|
||||
private import semmle.code.java.Collections
|
||||
private import semmle.code.java.controlflow.Guards
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA as Base
|
||||
private import semmle.code.java.dataflow.TaintTracking
|
||||
private import semmle.code.java.dataflow.TypeFlow
|
||||
private import semmle.code.java.dispatch.VirtualDispatch
|
||||
@@ -115,7 +115,7 @@ private predicate nodeWithAddition(FlowNode n, Variable v) {
|
||||
n.asField() = v
|
||||
or
|
||||
n.asSsa().getSourceVariable().getVariable() = v and
|
||||
(n.asSsa() instanceof BaseSsaUpdate or n.asSsa().(BaseSsaImplicitInit).isParameterDefinition(_))
|
||||
n.asSsa() instanceof Base::SsaExplicitWrite
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -46,14 +46,14 @@ class RightShiftOp extends Expr {
|
||||
}
|
||||
|
||||
private predicate boundedRead(VarRead read) {
|
||||
exists(SsaVariable v, ConditionBlock cb, ComparisonExpr comp, boolean testIsTrue |
|
||||
read = v.getAUse() and
|
||||
exists(SsaDefinition v, ConditionBlock cb, ComparisonExpr comp, boolean testIsTrue |
|
||||
read = v.getARead() and
|
||||
cb.controls(read.getBasicBlock(), testIsTrue) and
|
||||
cb.getCondition() = comp
|
||||
|
|
||||
comp.getLesserOperand() = v.getAUse() and testIsTrue = true
|
||||
comp.getLesserOperand() = v.getARead() and testIsTrue = true
|
||||
or
|
||||
comp.getGreaterOperand() = v.getAUse() and testIsTrue = false
|
||||
comp.getGreaterOperand() = v.getARead() and testIsTrue = false
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@ private predicate validationCall(MethodCall ma, VarAccess va) {
|
||||
}
|
||||
|
||||
private predicate validatedAccess(VarAccess va) {
|
||||
exists(SsaVariable v, MethodCall guardcall |
|
||||
va = v.getAUse() and
|
||||
validationCall(guardcall, v.getAUse())
|
||||
exists(SsaDefinition v, MethodCall guardcall |
|
||||
va = v.getARead() and
|
||||
validationCall(guardcall, v.getARead())
|
||||
|
|
||||
guardcall.(Guard).controls(va.getBasicBlock(), _)
|
||||
or
|
||||
|
||||
@@ -19,10 +19,10 @@ import semmle.code.java.dataflow.RangeUtils
|
||||
import semmle.code.java.dataflow.RangeAnalysis
|
||||
|
||||
pragma[nomagic]
|
||||
predicate ssaArrayLengthBound(SsaVariable arr, Bound b) {
|
||||
predicate ssaArrayLengthBound(SsaDefinition arr, Bound b) {
|
||||
exists(FieldAccess len |
|
||||
len.getField() instanceof ArrayLengthField and
|
||||
len.getQualifier() = arr.getAUse() and
|
||||
len.getQualifier() = arr.getARead() and
|
||||
b.getExpr() = len
|
||||
)
|
||||
}
|
||||
@@ -31,9 +31,9 @@ predicate ssaArrayLengthBound(SsaVariable arr, Bound b) {
|
||||
* Holds if the index expression of `aa` is less than or equal to the array length plus `k`.
|
||||
*/
|
||||
predicate boundedArrayAccess(ArrayAccess aa, int k) {
|
||||
exists(SsaVariable arr, Expr index, Bound b, int delta |
|
||||
exists(SsaDefinition arr, Expr index, Bound b, int delta |
|
||||
aa.getIndexExpr() = index and
|
||||
aa.getArray() = arr.getAUse() and
|
||||
aa.getArray() = arr.getARead() and
|
||||
bounded(index, b, delta, true, _)
|
||||
|
|
||||
ssaArrayLengthBound(arr, b) and
|
||||
|
||||
@@ -127,7 +127,7 @@ Expr overFlowCand() {
|
||||
c.getIntValue() >= 0
|
||||
)
|
||||
or
|
||||
exists(SsaExplicitUpdate x | result = x.getAUse() and x.getDefiningExpr() = overFlowCand())
|
||||
exists(SsaExplicitWrite x | result = x.getARead() and x.getDefiningExpr() = overFlowCand())
|
||||
or
|
||||
result.(AssignExpr).getRhs() = overFlowCand()
|
||||
or
|
||||
@@ -142,27 +142,27 @@ Expr overFlowCand() {
|
||||
predicate positiveOrNegative(Expr e) { positive(e) or negative(e) }
|
||||
|
||||
/** Gets an expression that equals `v` plus a positive or negative value. */
|
||||
Expr increaseOrDecreaseOfVar(SsaVariable v) {
|
||||
Expr increaseOrDecreaseOfVar(SsaDefinition v) {
|
||||
exists(AssignAddExpr add |
|
||||
result = add and
|
||||
positiveOrNegative(add.getDest()) and
|
||||
add.getRhs() = v.getAUse()
|
||||
add.getRhs() = v.getARead()
|
||||
)
|
||||
or
|
||||
exists(AddExpr add, Expr e |
|
||||
result = add and
|
||||
add.hasOperands(v.getAUse(), e) and
|
||||
add.hasOperands(v.getARead(), e) and
|
||||
positiveOrNegative(e)
|
||||
)
|
||||
or
|
||||
exists(SubExpr sub |
|
||||
result = sub and
|
||||
sub.getLeftOperand() = v.getAUse() and
|
||||
sub.getLeftOperand() = v.getARead() and
|
||||
positiveOrNegative(sub.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(SsaExplicitUpdate x |
|
||||
result = x.getAUse() and x.getDefiningExpr() = increaseOrDecreaseOfVar(v)
|
||||
exists(SsaExplicitWrite x |
|
||||
result = x.getARead() and x.getDefiningExpr() = increaseOrDecreaseOfVar(v)
|
||||
)
|
||||
or
|
||||
result.(AssignExpr).getRhs() = increaseOrDecreaseOfVar(v)
|
||||
@@ -172,7 +172,7 @@ Expr increaseOrDecreaseOfVar(SsaVariable v) {
|
||||
|
||||
predicate overFlowTest(ComparisonExpr comp) {
|
||||
(
|
||||
exists(SsaVariable v | comp.hasOperands(increaseOrDecreaseOfVar(v), v.getAUse()))
|
||||
exists(SsaDefinition v | comp.hasOperands(increaseOrDecreaseOfVar(v), v.getARead()))
|
||||
or
|
||||
comp.getLesserOperand() = overFlowCand() and
|
||||
comp.getGreaterOperand().(IntegerLiteral).getIntValue() = 0
|
||||
@@ -195,9 +195,9 @@ predicate concurrentModificationTest(BinaryExpr test) {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate guardedTest(EqualityTest test, Guard guard, boolean isEq, int i1, int i2) {
|
||||
exists(SsaVariable v, CompileTimeConstantExpr c1, CompileTimeConstantExpr c2 |
|
||||
guard.isEquality(v.getAUse(), c1, isEq) and
|
||||
test.hasOperands(v.getAUse(), c2) and
|
||||
exists(SsaDefinition v, CompileTimeConstantExpr c1, CompileTimeConstantExpr c2 |
|
||||
guard.isEquality(v.getARead(), c1, isEq) and
|
||||
test.hasOperands(v.getARead(), c2) and
|
||||
i1 = c1.getIntValue() and
|
||||
i2 = c2.getIntValue() and
|
||||
v.getSourceVariable().getType() instanceof IntegralType
|
||||
|
||||
@@ -27,14 +27,14 @@ class BoundKind extends string {
|
||||
*/
|
||||
predicate uselessTest(ConditionNode s1, BinaryExpr test, boolean testIsTrue) {
|
||||
exists(
|
||||
ConditionBlock cb, SsaVariable v, BinaryExpr cond, boolean condIsTrue, int k1, int k2,
|
||||
ConditionBlock cb, SsaDefinition v, BinaryExpr cond, boolean condIsTrue, int k1, int k2,
|
||||
CompileTimeConstantExpr c1, CompileTimeConstantExpr c2
|
||||
|
|
||||
s1.getCondition() = cond and
|
||||
cb.getCondition() = cond and
|
||||
cond.hasOperands(v.getAUse(), c1) and
|
||||
cond.hasOperands(v.getARead(), c1) and
|
||||
c1.getIntValue() = k1 and
|
||||
test.hasOperands(v.getAUse(), c2) and
|
||||
test.hasOperands(v.getARead(), c2) and
|
||||
c2.getIntValue() = k2 and
|
||||
v.getSourceVariable().getVariable() instanceof LocalScopeVariable and
|
||||
cb.controls(test.getBasicBlock(), condIsTrue) and
|
||||
@@ -49,7 +49,7 @@ predicate uselessTest(ConditionNode s1, BinaryExpr test, boolean testIsTrue) {
|
||||
)
|
||||
or
|
||||
exists(ComparisonExpr comp | comp = cond |
|
||||
comp.getLesserOperand() = v.getAUse() and
|
||||
comp.getLesserOperand() = v.getARead() and
|
||||
(
|
||||
condIsTrue = true and
|
||||
boundKind.isUpper() and
|
||||
@@ -60,7 +60,7 @@ predicate uselessTest(ConditionNode s1, BinaryExpr test, boolean testIsTrue) {
|
||||
(if comp.isStrict() then bound = k1 else bound = k1 + 1)
|
||||
)
|
||||
or
|
||||
comp.getGreaterOperand() = v.getAUse() and
|
||||
comp.getGreaterOperand() = v.getARead() and
|
||||
(
|
||||
condIsTrue = true and
|
||||
boundKind.isLower() and
|
||||
@@ -88,7 +88,7 @@ predicate uselessTest(ConditionNode s1, BinaryExpr test, boolean testIsTrue) {
|
||||
)
|
||||
or
|
||||
exists(ComparisonExpr comp | comp = test |
|
||||
comp.getLesserOperand() = v.getAUse() and
|
||||
comp.getLesserOperand() = v.getARead() and
|
||||
(
|
||||
boundKind.providesLowerBound() and
|
||||
testIsTrue = false and
|
||||
@@ -107,7 +107,7 @@ predicate uselessTest(ConditionNode s1, BinaryExpr test, boolean testIsTrue) {
|
||||
)
|
||||
)
|
||||
or
|
||||
comp.getGreaterOperand() = v.getAUse() and
|
||||
comp.getGreaterOperand() = v.getARead() and
|
||||
(
|
||||
boundKind.providesLowerBound() and
|
||||
testIsTrue = true and
|
||||
|
||||
@@ -8,9 +8,9 @@ import semmle.code.java.dataflow.SSA
|
||||
private Expr getAFieldRead(Field f) {
|
||||
result = f.getAnAccess()
|
||||
or
|
||||
exists(SsaExplicitUpdate v | v.getSourceVariable().getVariable() instanceof LocalScopeVariable |
|
||||
result = v.getAUse() and
|
||||
v.getDefiningExpr().(VariableAssign).getSource() = getAFieldRead(f)
|
||||
exists(SsaExplicitWrite v | v.getSourceVariable().getVariable() instanceof LocalScopeVariable |
|
||||
result = v.getARead() and
|
||||
v.getValue() = getAFieldRead(f)
|
||||
)
|
||||
or
|
||||
result.(AssignExpr).getSource() = getAFieldRead(f)
|
||||
|
||||
@@ -52,10 +52,10 @@ predicate failedLock(LockType t, BasicBlock lockblock, BasicBlock exblock) {
|
||||
(
|
||||
lock.asExpr() = t.getLockAccess()
|
||||
or
|
||||
exists(SsaExplicitUpdate lockbool |
|
||||
exists(SsaExplicitWrite lockbool |
|
||||
// Using the value of `t.getLockAccess()` ensures that it is a `tryLock` call.
|
||||
lock.asExpr() = lockbool.getAUse() and
|
||||
lockbool.getDefiningExpr().(VariableAssign).getSource() = t.getLockAccess()
|
||||
lock.asExpr() = lockbool.getARead() and
|
||||
lockbool.getValue() = t.getLockAccess()
|
||||
)
|
||||
) and
|
||||
(
|
||||
|
||||
@@ -37,11 +37,11 @@ predicate requiresInstanceOf(Expr e, VarAccess va, RefType t) {
|
||||
* `v` is not of type `sup`, which is a supertype of `t`.
|
||||
*/
|
||||
predicate contradictoryTypeCheck(Expr e, Variable v, RefType t, RefType sup, Expr cond) {
|
||||
exists(SsaVariable ssa |
|
||||
exists(SsaDefinition ssa |
|
||||
ssa.getSourceVariable().getVariable() = v and
|
||||
requiresInstanceOf(e, ssa.getAUse(), t) and
|
||||
requiresInstanceOf(e, ssa.getARead(), t) and
|
||||
sup = t.getAnAncestor() and
|
||||
instanceOfCheck(cond, ssa.getAUse(), sup) and
|
||||
instanceOfCheck(cond, ssa.getARead(), sup) and
|
||||
cond.(Guard).controls(e.getBasicBlock(), false) and
|
||||
not t instanceof ErrorType and
|
||||
not sup instanceof ErrorType
|
||||
|
||||
@@ -75,9 +75,9 @@ where
|
||||
loopWhileTrue(loop) and loopExitGuard(loop, cond)
|
||||
) and
|
||||
// None of the ssa variables in `cond` are updated inside the loop.
|
||||
forex(SsaVariable ssa, VarRead use | ssa.getAUse() = use and use.getParent*() = cond |
|
||||
not ssa.getCfgNode().getEnclosingStmt().getEnclosingStmt*() = loop or
|
||||
ssa.getCfgNode().asExpr().getParent*() = loop.(ForStmt).getAnInit()
|
||||
forex(SsaDefinition ssa, VarRead use | ssa.getARead() = use and use.getParent*() = cond |
|
||||
not ssa.getControlFlowNode().getEnclosingStmt().getEnclosingStmt*() = loop or
|
||||
ssa.getControlFlowNode().asExpr().getParent*() = loop.(ForStmt).getAnInit()
|
||||
) and
|
||||
// And `cond` does not use method calls, field reads, or array reads.
|
||||
not exists(MethodCall ma | ma.getParent*() = cond) and
|
||||
|
||||
@@ -14,7 +14,7 @@ private predicate emptyDecl(LocalVariableDeclExpr decl) {
|
||||
/** A dead variable update. */
|
||||
predicate deadLocal(VariableUpdate upd) {
|
||||
upd.getDestVar() instanceof LocalScopeVariable and
|
||||
not exists(SsaExplicitUpdate ssa | upd = ssa.getDefiningExpr()) and
|
||||
not exists(SsaExplicitWrite ssa | upd = ssa.getDefiningExpr()) and
|
||||
not emptyDecl(upd) and
|
||||
not readImplicitly(upd, _)
|
||||
}
|
||||
|
||||
@@ -42,9 +42,9 @@ class CheckSignaturesGuard extends Guard instanceof EqualityTest {
|
||||
}
|
||||
|
||||
predicate signatureChecked(Expr safe) {
|
||||
exists(CheckSignaturesGuard g, SsaVariable v |
|
||||
v.getAUse() = g.getCheckedExpr() and
|
||||
safe = v.getAUse() and
|
||||
exists(CheckSignaturesGuard g, SsaDefinition v |
|
||||
v.getARead() = g.getCheckedExpr() and
|
||||
safe = v.getARead() and
|
||||
g.controls(safe.getBasicBlock(), g.(EqualityTest).polarity())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -277,10 +277,7 @@ private module SinkModelGeneratorInput implements SinkModelGeneratorInputSig {
|
||||
|
||||
predicate sinkModelSanitizer(DataFlow::Node node) {
|
||||
// exclude variable capture jump steps
|
||||
exists(Ssa::SsaImplicitInit closure |
|
||||
closure.captures(_) and
|
||||
node.asExpr() = closure.getAFirstUse()
|
||||
)
|
||||
exists(Ssa::SsaCapturedDefinition closure | node.asExpr() = Ssa::ssaGetAFirstUse(closure))
|
||||
}
|
||||
|
||||
predicate apiSource(DataFlow::Node source) {
|
||||
|
||||
@@ -4,24 +4,23 @@
|
||||
| ModulusAnalysis.java:4:5:4:22 | ...=... | 0 | 43 | 0 |
|
||||
| ModulusAnalysis.java:4:5:4:22 | c2 | 0 | 43 | 0 |
|
||||
| ModulusAnalysis.java:4:20:4:21 | 43 | 0 | 43 | 0 |
|
||||
| ModulusAnalysis.java:7:13:7:22 | eq | SSA init(i) | 3 | 0 |
|
||||
| ModulusAnalysis.java:7:18:7:18 | i | SSA init(i) | 0 | 0 |
|
||||
| ModulusAnalysis.java:7:18:7:22 | ... + ... | SSA init(i) | 3 | 0 |
|
||||
| ModulusAnalysis.java:7:13:7:22 | eq | SSA param(i) | 3 | 0 |
|
||||
| ModulusAnalysis.java:7:18:7:18 | i | SSA param(i) | 0 | 0 |
|
||||
| ModulusAnalysis.java:7:18:7:22 | ... + ... | SSA param(i) | 3 | 0 |
|
||||
| ModulusAnalysis.java:7:22:7:22 | 3 | 0 | 3 | 0 |
|
||||
| ModulusAnalysis.java:9:13:9:29 | mul | 0 | 3 | 42 |
|
||||
| ModulusAnalysis.java:9:19:9:20 | eq | SSA def(eq) | 0 | 0 |
|
||||
| ModulusAnalysis.java:9:19:9:20 | eq | SSA init(i) | 3 | 0 |
|
||||
| ModulusAnalysis.java:9:19:9:20 | eq | SSA param(i) | 3 | 0 |
|
||||
| ModulusAnalysis.java:9:19:9:25 | ... * ... | 0 | 0 | 42 |
|
||||
| ModulusAnalysis.java:9:19:9:29 | ... + ... | 0 | 3 | 42 |
|
||||
| ModulusAnalysis.java:9:24:9:25 | c1 | 0 | 42 | 0 |
|
||||
| ModulusAnalysis.java:9:24:9:25 | c1 | SSA init(this.c1) | 0 | 0 |
|
||||
| ModulusAnalysis.java:9:24:9:25 | c1 | SSA entry def(this.c1) | 0 | 0 |
|
||||
| ModulusAnalysis.java:9:29:9:29 | 3 | 0 | 3 | 0 |
|
||||
| ModulusAnalysis.java:11:13:11:21 | seven | 0 | 7 | 0 |
|
||||
| ModulusAnalysis.java:11:21:11:21 | 7 | 0 | 7 | 0 |
|
||||
| ModulusAnalysis.java:12:13:12:15 | mul | 0 | 3 | 42 |
|
||||
| ModulusAnalysis.java:12:13:12:15 | mul | SSA def(mul) | 0 | 0 |
|
||||
| ModulusAnalysis.java:12:19:12:20 | c2 | 0 | 43 | 0 |
|
||||
| ModulusAnalysis.java:12:19:12:20 | c2 | SSA impl upd[untracked](this.c2) | 0 | 0 |
|
||||
| ModulusAnalysis.java:12:25:12:29 | seven | 0 | 7 | 0 |
|
||||
| ModulusAnalysis.java:12:25:12:29 | seven | SSA def(seven) | 0 | 0 |
|
||||
| ModulusAnalysis.java:13:32:13:34 | mul | 0 | 3 | 42 |
|
||||
@@ -29,49 +28,49 @@
|
||||
| ModulusAnalysis.java:13:32:13:34 | mul | SSA def(mul) | 0 | 0 |
|
||||
| ModulusAnalysis.java:16:13:18:23 | j | 0 | 3 | 4 |
|
||||
| ModulusAnalysis.java:16:17:18:23 | ...?...:... | 0 | 3 | 4 |
|
||||
| ModulusAnalysis.java:17:15:17:15 | i | SSA init(i) | 0 | 0 |
|
||||
| ModulusAnalysis.java:17:15:17:15 | i | SSA param(i) | 0 | 0 |
|
||||
| ModulusAnalysis.java:17:15:17:19 | ... * ... | 0 | 0 | 4 |
|
||||
| ModulusAnalysis.java:17:15:17:23 | ... + ... | 0 | 3 | 4 |
|
||||
| ModulusAnalysis.java:17:19:17:19 | 4 | 0 | 4 | 0 |
|
||||
| ModulusAnalysis.java:17:23:17:23 | 3 | 0 | 3 | 0 |
|
||||
| ModulusAnalysis.java:18:15:18:15 | i | SSA init(i) | 0 | 0 |
|
||||
| ModulusAnalysis.java:18:15:18:15 | i | SSA param(i) | 0 | 0 |
|
||||
| ModulusAnalysis.java:18:15:18:19 | ... * ... | 0 | 0 | 8 |
|
||||
| ModulusAnalysis.java:18:15:18:23 | ... + ... | 0 | 7 | 8 |
|
||||
| ModulusAnalysis.java:18:19:18:19 | 8 | 0 | 8 | 0 |
|
||||
| ModulusAnalysis.java:18:23:18:23 | 7 | 0 | 7 | 0 |
|
||||
| ModulusAnalysis.java:19:28:19:28 | j | 0 | 3 | 4 |
|
||||
| ModulusAnalysis.java:19:28:19:28 | j | SSA def(j) | 0 | 0 |
|
||||
| ModulusAnalysis.java:21:13:21:13 | x | SSA init(x) | 0 | 0 |
|
||||
| ModulusAnalysis.java:21:13:21:13 | x | SSA param(x) | 0 | 0 |
|
||||
| ModulusAnalysis.java:21:17:21:18 | c1 | 0 | 42 | 0 |
|
||||
| ModulusAnalysis.java:21:17:21:18 | c1 | SSA init(this.c1) | 0 | 0 |
|
||||
| ModulusAnalysis.java:21:17:21:18 | c1 | SSA entry def(this.c1) | 0 | 0 |
|
||||
| ModulusAnalysis.java:21:23:21:23 | 3 | 0 | 3 | 0 |
|
||||
| ModulusAnalysis.java:21:28:21:28 | y | SSA init(y) | 0 | 0 |
|
||||
| ModulusAnalysis.java:21:28:21:28 | y | SSA param(y) | 0 | 0 |
|
||||
| ModulusAnalysis.java:21:32:21:33 | c1 | 0 | 42 | 0 |
|
||||
| ModulusAnalysis.java:21:32:21:33 | c1 | SSA init(this.c1) | 0 | 0 |
|
||||
| ModulusAnalysis.java:21:32:21:33 | c1 | SSA entry def(this.c1) | 0 | 0 |
|
||||
| ModulusAnalysis.java:21:38:21:38 | 7 | 0 | 7 | 0 |
|
||||
| ModulusAnalysis.java:22:32:22:32 | x | 0 | 3 | 42 |
|
||||
| ModulusAnalysis.java:22:32:22:32 | x | SSA init(x) | 0 | 0 |
|
||||
| ModulusAnalysis.java:22:32:22:32 | x | SSA param(x) | 0 | 0 |
|
||||
| ModulusAnalysis.java:22:32:22:36 | ... + ... | 0 | 10 | 42 |
|
||||
| ModulusAnalysis.java:22:32:22:36 | ... + ... | SSA init(x) | 7 | 42 |
|
||||
| ModulusAnalysis.java:22:32:22:36 | ... + ... | SSA init(y) | 3 | 42 |
|
||||
| ModulusAnalysis.java:22:32:22:36 | ... + ... | SSA param(x) | 7 | 42 |
|
||||
| ModulusAnalysis.java:22:32:22:36 | ... + ... | SSA param(y) | 3 | 42 |
|
||||
| ModulusAnalysis.java:22:36:22:36 | y | 0 | 7 | 42 |
|
||||
| ModulusAnalysis.java:22:36:22:36 | y | SSA init(y) | 0 | 0 |
|
||||
| ModulusAnalysis.java:25:13:25:13 | x | SSA init(x) | 0 | 0 |
|
||||
| ModulusAnalysis.java:22:36:22:36 | y | SSA param(y) | 0 | 0 |
|
||||
| ModulusAnalysis.java:25:13:25:13 | x | SSA param(x) | 0 | 0 |
|
||||
| ModulusAnalysis.java:25:17:25:18 | c1 | 0 | 42 | 0 |
|
||||
| ModulusAnalysis.java:25:17:25:18 | c1 | SSA init(this.c1) | 0 | 0 |
|
||||
| ModulusAnalysis.java:25:17:25:18 | c1 | SSA entry def(this.c1) | 0 | 0 |
|
||||
| ModulusAnalysis.java:25:23:25:23 | 3 | 0 | 3 | 0 |
|
||||
| ModulusAnalysis.java:25:28:25:28 | y | SSA init(y) | 0 | 0 |
|
||||
| ModulusAnalysis.java:25:28:25:28 | y | SSA param(y) | 0 | 0 |
|
||||
| ModulusAnalysis.java:25:32:25:33 | c1 | 0 | 42 | 0 |
|
||||
| ModulusAnalysis.java:25:32:25:33 | c1 | SSA init(this.c1) | 0 | 0 |
|
||||
| ModulusAnalysis.java:25:32:25:33 | c1 | SSA entry def(this.c1) | 0 | 0 |
|
||||
| ModulusAnalysis.java:25:38:25:38 | 7 | 0 | 7 | 0 |
|
||||
| ModulusAnalysis.java:26:32:26:32 | x | 0 | 3 | 42 |
|
||||
| ModulusAnalysis.java:26:32:26:32 | x | SSA init(x) | 0 | 0 |
|
||||
| ModulusAnalysis.java:26:32:26:32 | x | SSA param(x) | 0 | 0 |
|
||||
| ModulusAnalysis.java:26:32:26:36 | ... - ... | 0 | 38 | 42 |
|
||||
| ModulusAnalysis.java:26:32:26:36 | ... - ... | SSA init(x) | 35 | 42 |
|
||||
| ModulusAnalysis.java:26:32:26:36 | ... - ... | SSA param(x) | 35 | 42 |
|
||||
| ModulusAnalysis.java:26:36:26:36 | y | 0 | 7 | 42 |
|
||||
| ModulusAnalysis.java:26:36:26:36 | y | SSA init(y) | 0 | 0 |
|
||||
| ModulusAnalysis.java:26:36:26:36 | y | SSA param(y) | 0 | 0 |
|
||||
| ModulusAnalysis.java:29:13:29:35 | l | 0 | 1 | 4 |
|
||||
| ModulusAnalysis.java:29:17:29:26 | arr.length | SSA impl upd[untracked](arr.length) | 0 | 0 |
|
||||
| ModulusAnalysis.java:29:17:29:26 | arr.length | arr.length | 0 | 0 |
|
||||
| ModulusAnalysis.java:29:17:29:30 | ... * ... | 0 | 0 | 4 |
|
||||
| ModulusAnalysis.java:29:17:29:35 | ... - ... | 0 | 1 | 4 |
|
||||
| ModulusAnalysis.java:29:30:29:30 | 4 | 0 | 4 | 0 |
|
||||
@@ -87,13 +86,13 @@
|
||||
| ModulusAnalysis.java:33:28:33:28 | l | 0 | 1 | 4 |
|
||||
| ModulusAnalysis.java:33:28:33:28 | l | SSA def(l) | 0 | 0 |
|
||||
| ModulusAnalysis.java:36:13:36:25 | ...=... | 0 | 3 | 4 |
|
||||
| ModulusAnalysis.java:36:17:36:17 | i | SSA init(i) | 0 | 0 |
|
||||
| ModulusAnalysis.java:36:17:36:17 | i | SSA param(i) | 0 | 0 |
|
||||
| ModulusAnalysis.java:36:17:36:21 | ... * ... | 0 | 0 | 4 |
|
||||
| ModulusAnalysis.java:36:17:36:25 | ... + ... | 0 | 3 | 4 |
|
||||
| ModulusAnalysis.java:36:21:36:21 | 4 | 0 | 4 | 0 |
|
||||
| ModulusAnalysis.java:36:25:36:25 | 3 | 0 | 3 | 0 |
|
||||
| ModulusAnalysis.java:39:13:39:25 | ...=... | 0 | 7 | 8 |
|
||||
| ModulusAnalysis.java:39:17:39:17 | i | SSA init(i) | 0 | 0 |
|
||||
| ModulusAnalysis.java:39:17:39:17 | i | SSA param(i) | 0 | 0 |
|
||||
| ModulusAnalysis.java:39:17:39:21 | ... * ... | 0 | 0 | 8 |
|
||||
| ModulusAnalysis.java:39:17:39:25 | ... + ... | 0 | 7 | 8 |
|
||||
| ModulusAnalysis.java:39:21:39:21 | 8 | 0 | 8 | 0 |
|
||||
@@ -104,22 +103,22 @@
|
||||
| ModulusAnalysis.java:44:32:44:32 | j | SSA phi(j) | 0 | 0 |
|
||||
| ModulusAnalysis.java:46:32:46:32 | j | 0 | 3 | 4 |
|
||||
| ModulusAnalysis.java:46:32:46:32 | j | SSA phi(j) | 0 | 0 |
|
||||
| ModulusAnalysis.java:49:14:49:14 | x | SSA init(x) | 0 | 0 |
|
||||
| ModulusAnalysis.java:49:14:49:14 | x | SSA param(x) | 0 | 0 |
|
||||
| ModulusAnalysis.java:49:18:49:19 | 15 | 0 | 15 | 0 |
|
||||
| ModulusAnalysis.java:49:25:49:25 | 3 | 0 | 3 | 0 |
|
||||
| ModulusAnalysis.java:50:32:50:32 | x | 0 | 3 | 16 |
|
||||
| ModulusAnalysis.java:50:32:50:32 | x | SSA init(x) | 0 | 0 |
|
||||
| ModulusAnalysis.java:50:32:50:32 | x | SSA param(x) | 0 | 0 |
|
||||
| ModulusAnalysis.java:56:18:56:22 | i | 0 | 0 | 0 |
|
||||
| ModulusAnalysis.java:56:22:56:22 | 0 | 0 | 0 | 0 |
|
||||
| ModulusAnalysis.java:56:25:56:25 | i | SSA phi(i) | 0 | 0 |
|
||||
| ModulusAnalysis.java:56:29:56:31 | cap | SSA init(cap) | 0 | 0 |
|
||||
| ModulusAnalysis.java:56:29:56:31 | cap | SSA param(cap) | 0 | 0 |
|
||||
| ModulusAnalysis.java:56:34:56:34 | i | SSA phi(i) | 0 | 0 |
|
||||
| ModulusAnalysis.java:56:34:56:36 | ...++ | SSA phi(i) | 0 | 0 |
|
||||
| ModulusAnalysis.java:57:32:57:32 | i | SSA phi(i) | 0 | 0 |
|
||||
| ModulusAnalysis.java:59:18:59:22 | j | 0 | 0 | 0 |
|
||||
| ModulusAnalysis.java:59:22:59:22 | 0 | 0 | 0 | 0 |
|
||||
| ModulusAnalysis.java:59:25:59:25 | j | SSA phi(j) | 0 | 0 |
|
||||
| ModulusAnalysis.java:59:29:59:31 | cap | SSA init(cap) | 0 | 0 |
|
||||
| ModulusAnalysis.java:59:29:59:31 | cap | SSA param(cap) | 0 | 0 |
|
||||
| ModulusAnalysis.java:59:34:59:34 | j | SSA phi(j) | 0 | 0 |
|
||||
| ModulusAnalysis.java:59:34:59:39 | ...+=... | SSA phi(j) | 1 | 0 |
|
||||
| ModulusAnalysis.java:59:39:59:39 | 1 | 0 | 1 | 0 |
|
||||
@@ -129,7 +128,7 @@
|
||||
| ModulusAnalysis.java:62:25:62:25 | k | 0 | 0 | 3 |
|
||||
| ModulusAnalysis.java:62:25:62:25 | k | SSA def(k) | 0 | 3 |
|
||||
| ModulusAnalysis.java:62:25:62:25 | k | SSA phi(k) | 0 | 0 |
|
||||
| ModulusAnalysis.java:62:29:62:31 | cap | SSA init(cap) | 0 | 0 |
|
||||
| ModulusAnalysis.java:62:29:62:31 | cap | SSA param(cap) | 0 | 0 |
|
||||
| ModulusAnalysis.java:62:34:62:34 | k | 0 | 0 | 3 |
|
||||
| ModulusAnalysis.java:62:34:62:34 | k | SSA def(k) | 0 | 3 |
|
||||
| ModulusAnalysis.java:62:34:62:34 | k | SSA phi(k) | 0 | 0 |
|
||||
|
||||
@@ -1,232 +1,232 @@
|
||||
| A.java:3:9:3:9 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:3:9:3:9 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:3:9:3:9 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:3:9:3:9 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:3:13:3:15 | 500 | 0 | 500 | lower | NoReason |
|
||||
| A.java:3:13:3:15 | 500 | 0 | 500 | upper | NoReason |
|
||||
| A.java:4:11:4:11 | x | 0 | 499 | upper | ... < ... |
|
||||
| A.java:4:11:4:11 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:4:11:4:11 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:4:11:4:11 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:4:11:4:11 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:4:15:4:17 | 400 | 0 | 400 | lower | NoReason |
|
||||
| A.java:4:15:4:17 | 400 | 0 | 400 | upper | NoReason |
|
||||
| A.java:5:16:5:16 | x | 0 | 401 | lower | ... > ... |
|
||||
| A.java:5:16:5:16 | x | 0 | 499 | upper | ... < ... |
|
||||
| A.java:5:16:5:16 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:5:16:5:16 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:8:11:8:11 | y | SSA init(y) | 0 | lower | NoReason |
|
||||
| A.java:8:11:8:11 | y | SSA init(y) | 0 | upper | NoReason |
|
||||
| A.java:8:11:8:15 | ... - ... | SSA init(y) | -2 | lower | NoReason |
|
||||
| A.java:8:11:8:15 | ... - ... | SSA init(y) | -2 | upper | NoReason |
|
||||
| A.java:5:16:5:16 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:5:16:5:16 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:8:11:8:11 | y | SSA param(y) | 0 | lower | NoReason |
|
||||
| A.java:8:11:8:11 | y | SSA param(y) | 0 | upper | NoReason |
|
||||
| A.java:8:11:8:15 | ... - ... | SSA param(y) | -2 | lower | NoReason |
|
||||
| A.java:8:11:8:15 | ... - ... | SSA param(y) | -2 | upper | NoReason |
|
||||
| A.java:8:15:8:15 | 2 | 0 | 2 | lower | NoReason |
|
||||
| A.java:8:15:8:15 | 2 | 0 | 2 | upper | NoReason |
|
||||
| A.java:8:20:8:20 | x | 0 | 400 | upper | ... > ... |
|
||||
| A.java:8:20:8:20 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:8:20:8:20 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:8:20:8:20 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:8:20:8:20 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:8:25:8:25 | y | 0 | 402 | upper | ... == ... |
|
||||
| A.java:8:25:8:25 | y | SSA init(x) | 2 | lower | ... == ... |
|
||||
| A.java:8:25:8:25 | y | SSA init(x) | 2 | upper | ... == ... |
|
||||
| A.java:8:25:8:25 | y | SSA init(y) | 0 | lower | NoReason |
|
||||
| A.java:8:25:8:25 | y | SSA init(y) | 0 | upper | NoReason |
|
||||
| A.java:8:25:8:25 | y | SSA param(x) | 2 | lower | ... == ... |
|
||||
| A.java:8:25:8:25 | y | SSA param(x) | 2 | upper | ... == ... |
|
||||
| A.java:8:25:8:25 | y | SSA param(y) | 0 | lower | NoReason |
|
||||
| A.java:8:25:8:25 | y | SSA param(y) | 0 | upper | NoReason |
|
||||
| A.java:8:29:8:31 | 300 | 0 | 300 | lower | NoReason |
|
||||
| A.java:8:29:8:31 | 300 | 0 | 300 | upper | NoReason |
|
||||
| A.java:9:16:9:16 | x | 0 | 299 | lower | ... > ... |
|
||||
| A.java:9:16:9:16 | x | 0 | 400 | upper | ... > ... |
|
||||
| A.java:9:16:9:16 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:9:16:9:16 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:9:16:9:16 | x | SSA init(y) | -2 | lower | ... == ... |
|
||||
| A.java:9:16:9:16 | x | SSA init(y) | -2 | upper | ... == ... |
|
||||
| A.java:9:16:9:16 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:9:16:9:16 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:9:16:9:16 | x | SSA param(y) | -2 | lower | ... == ... |
|
||||
| A.java:9:16:9:16 | x | SSA param(y) | -2 | upper | ... == ... |
|
||||
| A.java:9:16:9:20 | ... + ... | 0 | 600 | lower | ... > ... |
|
||||
| A.java:9:16:9:20 | ... + ... | 0 | 802 | upper | ... == ... |
|
||||
| A.java:9:16:9:20 | ... + ... | 0 | 802 | upper | ... > ... |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA init(x) | 301 | lower | ... == ... |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA init(x) | 301 | lower | NoReason |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA init(x) | 402 | upper | ... == ... |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA init(x) | 402 | upper | NoReason |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA init(y) | 299 | lower | ... == ... |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA init(y) | 299 | lower | NoReason |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA init(y) | 400 | upper | ... == ... |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA init(y) | 400 | upper | NoReason |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA param(x) | 301 | lower | ... == ... |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA param(x) | 301 | lower | NoReason |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA param(x) | 402 | upper | ... == ... |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA param(x) | 402 | upper | NoReason |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA param(y) | 299 | lower | ... == ... |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA param(y) | 299 | lower | NoReason |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA param(y) | 400 | upper | ... == ... |
|
||||
| A.java:9:16:9:20 | ... + ... | SSA param(y) | 400 | upper | NoReason |
|
||||
| A.java:9:20:9:20 | y | 0 | 301 | lower | ... > ... |
|
||||
| A.java:9:20:9:20 | y | 0 | 402 | upper | ... == ... |
|
||||
| A.java:9:20:9:20 | y | SSA init(x) | 2 | lower | ... == ... |
|
||||
| A.java:9:20:9:20 | y | SSA init(x) | 2 | upper | ... == ... |
|
||||
| A.java:9:20:9:20 | y | SSA init(y) | 0 | lower | NoReason |
|
||||
| A.java:9:20:9:20 | y | SSA init(y) | 0 | upper | NoReason |
|
||||
| A.java:9:20:9:20 | y | SSA param(x) | 2 | lower | ... == ... |
|
||||
| A.java:9:20:9:20 | y | SSA param(x) | 2 | upper | ... == ... |
|
||||
| A.java:9:20:9:20 | y | SSA param(y) | 0 | lower | NoReason |
|
||||
| A.java:9:20:9:20 | y | SSA param(y) | 0 | upper | NoReason |
|
||||
| A.java:12:11:12:11 | x | 0 | 400 | upper | ... > ... |
|
||||
| A.java:12:11:12:11 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:12:11:12:11 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:12:16:12:16 | y | SSA init(y) | 0 | lower | NoReason |
|
||||
| A.java:12:16:12:16 | y | SSA init(y) | 0 | upper | NoReason |
|
||||
| A.java:12:16:12:20 | ... + ... | SSA init(y) | 1 | lower | NoReason |
|
||||
| A.java:12:16:12:20 | ... + ... | SSA init(y) | 1 | upper | NoReason |
|
||||
| A.java:12:11:12:11 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:12:11:12:11 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:12:16:12:16 | y | SSA param(y) | 0 | lower | NoReason |
|
||||
| A.java:12:16:12:16 | y | SSA param(y) | 0 | upper | NoReason |
|
||||
| A.java:12:16:12:20 | ... + ... | SSA param(y) | 1 | lower | NoReason |
|
||||
| A.java:12:16:12:20 | ... + ... | SSA param(y) | 1 | upper | NoReason |
|
||||
| A.java:12:20:12:20 | 1 | 0 | 1 | lower | NoReason |
|
||||
| A.java:12:20:12:20 | 1 | 0 | 1 | upper | NoReason |
|
||||
| A.java:13:13:13:23 | sum | SSA init(y) | 400 | upper | NoReason |
|
||||
| A.java:13:13:13:23 | sum | SSA param(y) | 400 | upper | NoReason |
|
||||
| A.java:13:19:13:19 | x | 0 | 400 | upper | ... > ... |
|
||||
| A.java:13:19:13:19 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:13:19:13:19 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:13:19:13:23 | ... + ... | SSA init(y) | 400 | upper | NoReason |
|
||||
| A.java:13:23:13:23 | y | SSA init(y) | 0 | lower | NoReason |
|
||||
| A.java:13:23:13:23 | y | SSA init(y) | 0 | upper | NoReason |
|
||||
| A.java:13:19:13:19 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:13:19:13:19 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:13:19:13:23 | ... + ... | SSA param(y) | 400 | upper | NoReason |
|
||||
| A.java:13:23:13:23 | y | SSA param(y) | 0 | lower | NoReason |
|
||||
| A.java:13:23:13:23 | y | SSA param(y) | 0 | upper | NoReason |
|
||||
| A.java:15:13:15:13 | y | 0 | 399 | upper | ... != ... |
|
||||
| A.java:15:13:15:13 | y | SSA init(x) | -1 | lower | ... != ... |
|
||||
| A.java:15:13:15:13 | y | SSA init(x) | -1 | upper | ... != ... |
|
||||
| A.java:15:13:15:13 | y | SSA init(y) | 0 | lower | NoReason |
|
||||
| A.java:15:13:15:13 | y | SSA init(y) | 0 | upper | NoReason |
|
||||
| A.java:15:13:15:13 | y | SSA param(x) | -1 | lower | ... != ... |
|
||||
| A.java:15:13:15:13 | y | SSA param(x) | -1 | upper | ... != ... |
|
||||
| A.java:15:13:15:13 | y | SSA param(y) | 0 | lower | NoReason |
|
||||
| A.java:15:13:15:13 | y | SSA param(y) | 0 | upper | NoReason |
|
||||
| A.java:15:17:15:19 | 300 | 0 | 300 | lower | NoReason |
|
||||
| A.java:15:17:15:19 | 300 | 0 | 300 | upper | NoReason |
|
||||
| A.java:16:15:16:25 | sum | 0 | 603 | lower | ... > ... |
|
||||
| A.java:16:15:16:25 | sum | 0 | 799 | upper | ... != ... |
|
||||
| A.java:16:15:16:25 | sum | 0 | 799 | upper | ... > ... |
|
||||
| A.java:16:15:16:25 | sum | SSA init(x) | 301 | lower | ... != ... |
|
||||
| A.java:16:15:16:25 | sum | SSA init(x) | 301 | lower | NoReason |
|
||||
| A.java:16:15:16:25 | sum | SSA init(x) | 399 | upper | ... != ... |
|
||||
| A.java:16:15:16:25 | sum | SSA init(x) | 399 | upper | NoReason |
|
||||
| A.java:16:15:16:25 | sum | SSA init(y) | 302 | lower | ... != ... |
|
||||
| A.java:16:15:16:25 | sum | SSA init(y) | 302 | lower | NoReason |
|
||||
| A.java:16:15:16:25 | sum | SSA init(y) | 400 | upper | ... != ... |
|
||||
| A.java:16:15:16:25 | sum | SSA init(y) | 400 | upper | NoReason |
|
||||
| A.java:16:15:16:25 | sum | SSA param(x) | 301 | lower | ... != ... |
|
||||
| A.java:16:15:16:25 | sum | SSA param(x) | 301 | lower | NoReason |
|
||||
| A.java:16:15:16:25 | sum | SSA param(x) | 399 | upper | ... != ... |
|
||||
| A.java:16:15:16:25 | sum | SSA param(x) | 399 | upper | NoReason |
|
||||
| A.java:16:15:16:25 | sum | SSA param(y) | 302 | lower | ... != ... |
|
||||
| A.java:16:15:16:25 | sum | SSA param(y) | 302 | lower | NoReason |
|
||||
| A.java:16:15:16:25 | sum | SSA param(y) | 400 | upper | ... != ... |
|
||||
| A.java:16:15:16:25 | sum | SSA param(y) | 400 | upper | NoReason |
|
||||
| A.java:16:21:16:21 | x | 0 | 302 | lower | ... > ... |
|
||||
| A.java:16:21:16:21 | x | 0 | 400 | upper | ... > ... |
|
||||
| A.java:16:21:16:21 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:16:21:16:21 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:16:21:16:21 | x | SSA init(y) | 1 | lower | ... != ... |
|
||||
| A.java:16:21:16:21 | x | SSA init(y) | 1 | upper | ... != ... |
|
||||
| A.java:16:21:16:21 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:16:21:16:21 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:16:21:16:21 | x | SSA param(y) | 1 | lower | ... != ... |
|
||||
| A.java:16:21:16:21 | x | SSA param(y) | 1 | upper | ... != ... |
|
||||
| A.java:16:21:16:25 | ... + ... | 0 | 603 | lower | ... > ... |
|
||||
| A.java:16:21:16:25 | ... + ... | 0 | 799 | upper | ... != ... |
|
||||
| A.java:16:21:16:25 | ... + ... | 0 | 799 | upper | ... > ... |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA init(x) | 301 | lower | ... != ... |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA init(x) | 301 | lower | NoReason |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA init(x) | 399 | upper | ... != ... |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA init(x) | 399 | upper | NoReason |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA init(y) | 302 | lower | ... != ... |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA init(y) | 302 | lower | NoReason |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA init(y) | 400 | upper | ... != ... |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA init(y) | 400 | upper | NoReason |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA param(x) | 301 | lower | ... != ... |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA param(x) | 301 | lower | NoReason |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA param(x) | 399 | upper | ... != ... |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA param(x) | 399 | upper | NoReason |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA param(y) | 302 | lower | ... != ... |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA param(y) | 302 | lower | NoReason |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA param(y) | 400 | upper | ... != ... |
|
||||
| A.java:16:21:16:25 | ... + ... | SSA param(y) | 400 | upper | NoReason |
|
||||
| A.java:16:25:16:25 | y | 0 | 301 | lower | ... > ... |
|
||||
| A.java:16:25:16:25 | y | 0 | 399 | upper | ... != ... |
|
||||
| A.java:16:25:16:25 | y | SSA init(x) | -1 | lower | ... != ... |
|
||||
| A.java:16:25:16:25 | y | SSA init(x) | -1 | upper | ... != ... |
|
||||
| A.java:16:25:16:25 | y | SSA init(y) | 0 | lower | NoReason |
|
||||
| A.java:16:25:16:25 | y | SSA init(y) | 0 | upper | NoReason |
|
||||
| A.java:16:25:16:25 | y | SSA param(x) | -1 | lower | ... != ... |
|
||||
| A.java:16:25:16:25 | y | SSA param(x) | -1 | upper | ... != ... |
|
||||
| A.java:16:25:16:25 | y | SSA param(y) | 0 | lower | NoReason |
|
||||
| A.java:16:25:16:25 | y | SSA param(y) | 0 | upper | NoReason |
|
||||
| A.java:20:11:20:11 | x | 0 | 400 | upper | ... > ... |
|
||||
| A.java:20:11:20:11 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:20:11:20:11 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:20:11:20:11 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:20:11:20:11 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:20:15:20:17 | 500 | 0 | 500 | lower | NoReason |
|
||||
| A.java:20:15:20:17 | 500 | 0 | 500 | upper | NoReason |
|
||||
| A.java:21:16:21:16 | x | 0 | 400 | upper | ... > ... |
|
||||
| A.java:21:16:21:16 | x | 0 | 501 | lower | ... > ... |
|
||||
| A.java:21:16:21:16 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:21:16:21:16 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:21:16:21:16 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:21:16:21:16 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:25:12:25:12 | 0 | 0 | 0 | lower | NoReason |
|
||||
| A.java:25:12:25:12 | 0 | 0 | 0 | upper | NoReason |
|
||||
| A.java:29:9:29:9 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:29:9:29:9 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:29:9:29:9 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:29:9:29:9 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:29:13:29:15 | 500 | 0 | 500 | lower | NoReason |
|
||||
| A.java:29:13:29:15 | 500 | 0 | 500 | upper | NoReason |
|
||||
| A.java:30:11:30:11 | x | 0 | 499 | upper | ... < ... |
|
||||
| A.java:30:11:30:11 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:30:11:30:11 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:30:11:30:11 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:30:11:30:11 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:30:15:30:17 | 400 | 0 | 400 | lower | NoReason |
|
||||
| A.java:30:15:30:17 | 400 | 0 | 400 | upper | NoReason |
|
||||
| A.java:31:16:31:16 | x | 0 | 401 | lower | ... > ... |
|
||||
| A.java:31:16:31:16 | x | 0 | 499 | upper | ... < ... |
|
||||
| A.java:31:16:31:16 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:31:16:31:16 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:34:11:34:11 | y | SSA init(y) | 0 | lower | NoReason |
|
||||
| A.java:34:11:34:11 | y | SSA init(y) | 0 | upper | NoReason |
|
||||
| A.java:31:16:31:16 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:31:16:31:16 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:34:11:34:11 | y | SSA param(y) | 0 | lower | NoReason |
|
||||
| A.java:34:11:34:11 | y | SSA param(y) | 0 | upper | NoReason |
|
||||
| A.java:34:16:34:16 | x | 0 | 400 | upper | ... > ... |
|
||||
| A.java:34:16:34:16 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:34:16:34:16 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:34:16:34:16 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:34:16:34:16 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:34:16:34:20 | ... - ... | 0 | 399 | upper | ... > ... |
|
||||
| A.java:34:16:34:20 | ... - ... | SSA init(x) | -1 | lower | NoReason |
|
||||
| A.java:34:16:34:20 | ... - ... | SSA init(x) | -1 | upper | NoReason |
|
||||
| A.java:34:16:34:20 | ... - ... | SSA param(x) | -1 | lower | NoReason |
|
||||
| A.java:34:16:34:20 | ... - ... | SSA param(x) | -1 | upper | NoReason |
|
||||
| A.java:34:20:34:20 | 1 | 0 | 1 | lower | NoReason |
|
||||
| A.java:34:20:34:20 | 1 | 0 | 1 | upper | NoReason |
|
||||
| A.java:34:25:34:25 | y | 0 | 399 | upper | ... == ... |
|
||||
| A.java:34:25:34:25 | y | SSA init(x) | -1 | lower | ... == ... |
|
||||
| A.java:34:25:34:25 | y | SSA init(x) | -1 | upper | ... == ... |
|
||||
| A.java:34:25:34:25 | y | SSA init(y) | 0 | lower | NoReason |
|
||||
| A.java:34:25:34:25 | y | SSA init(y) | 0 | upper | NoReason |
|
||||
| A.java:34:25:34:25 | y | SSA param(x) | -1 | lower | ... == ... |
|
||||
| A.java:34:25:34:25 | y | SSA param(x) | -1 | upper | ... == ... |
|
||||
| A.java:34:25:34:25 | y | SSA param(y) | 0 | lower | NoReason |
|
||||
| A.java:34:25:34:25 | y | SSA param(y) | 0 | upper | NoReason |
|
||||
| A.java:34:29:34:31 | 300 | 0 | 300 | lower | NoReason |
|
||||
| A.java:34:29:34:31 | 300 | 0 | 300 | upper | NoReason |
|
||||
| A.java:34:36:34:36 | y | 0 | 301 | lower | ... > ... |
|
||||
| A.java:34:36:34:36 | y | 0 | 399 | upper | ... == ... |
|
||||
| A.java:34:36:34:36 | y | SSA init(x) | -1 | lower | ... == ... |
|
||||
| A.java:34:36:34:36 | y | SSA init(x) | -1 | upper | ... == ... |
|
||||
| A.java:34:36:34:36 | y | SSA init(y) | 0 | lower | NoReason |
|
||||
| A.java:34:36:34:36 | y | SSA init(y) | 0 | upper | NoReason |
|
||||
| A.java:34:36:34:36 | y | SSA param(x) | -1 | lower | ... == ... |
|
||||
| A.java:34:36:34:36 | y | SSA param(x) | -1 | upper | ... == ... |
|
||||
| A.java:34:36:34:36 | y | SSA param(y) | 0 | lower | NoReason |
|
||||
| A.java:34:36:34:36 | y | SSA param(y) | 0 | upper | NoReason |
|
||||
| A.java:34:36:34:40 | ... + ... | 0 | 303 | lower | ... > ... |
|
||||
| A.java:34:36:34:40 | ... + ... | 0 | 401 | upper | ... == ... |
|
||||
| A.java:34:36:34:40 | ... + ... | SSA init(x) | 1 | lower | ... == ... |
|
||||
| A.java:34:36:34:40 | ... + ... | SSA init(x) | 1 | upper | ... == ... |
|
||||
| A.java:34:36:34:40 | ... + ... | SSA init(y) | 2 | lower | NoReason |
|
||||
| A.java:34:36:34:40 | ... + ... | SSA init(y) | 2 | upper | NoReason |
|
||||
| A.java:34:36:34:40 | ... + ... | SSA param(x) | 1 | lower | ... == ... |
|
||||
| A.java:34:36:34:40 | ... + ... | SSA param(x) | 1 | upper | ... == ... |
|
||||
| A.java:34:36:34:40 | ... + ... | SSA param(y) | 2 | lower | NoReason |
|
||||
| A.java:34:36:34:40 | ... + ... | SSA param(y) | 2 | upper | NoReason |
|
||||
| A.java:34:40:34:40 | 2 | 0 | 2 | lower | NoReason |
|
||||
| A.java:34:40:34:40 | 2 | 0 | 2 | upper | NoReason |
|
||||
| A.java:34:45:34:45 | z | SSA init(z) | 0 | lower | NoReason |
|
||||
| A.java:34:45:34:45 | z | SSA init(z) | 0 | upper | NoReason |
|
||||
| A.java:34:45:34:45 | z | SSA param(z) | 0 | lower | NoReason |
|
||||
| A.java:34:45:34:45 | z | SSA param(z) | 0 | upper | NoReason |
|
||||
| A.java:34:50:34:50 | z | 0 | 303 | lower | ... == ... |
|
||||
| A.java:34:50:34:50 | z | 0 | 401 | upper | ... == ... |
|
||||
| A.java:34:50:34:50 | z | SSA init(x) | 1 | lower | ... == ... |
|
||||
| A.java:34:50:34:50 | z | SSA init(x) | 1 | upper | ... == ... |
|
||||
| A.java:34:50:34:50 | z | SSA init(y) | 2 | lower | ... == ... |
|
||||
| A.java:34:50:34:50 | z | SSA init(y) | 2 | upper | ... == ... |
|
||||
| A.java:34:50:34:50 | z | SSA init(z) | 0 | lower | NoReason |
|
||||
| A.java:34:50:34:50 | z | SSA init(z) | 0 | upper | NoReason |
|
||||
| A.java:34:50:34:50 | z | SSA param(x) | 1 | lower | ... == ... |
|
||||
| A.java:34:50:34:50 | z | SSA param(x) | 1 | upper | ... == ... |
|
||||
| A.java:34:50:34:50 | z | SSA param(y) | 2 | lower | ... == ... |
|
||||
| A.java:34:50:34:50 | z | SSA param(y) | 2 | upper | ... == ... |
|
||||
| A.java:34:50:34:50 | z | SSA param(z) | 0 | lower | NoReason |
|
||||
| A.java:34:50:34:50 | z | SSA param(z) | 0 | upper | NoReason |
|
||||
| A.java:34:55:34:57 | 350 | 0 | 350 | lower | NoReason |
|
||||
| A.java:34:55:34:57 | 350 | 0 | 350 | upper | NoReason |
|
||||
| A.java:35:16:35:16 | x | 0 | 349 | lower | ... == ... |
|
||||
| A.java:35:16:35:16 | x | 0 | 349 | upper | ... == ... |
|
||||
| A.java:35:16:35:16 | x | SSA init(x) | 0 | lower | NoReason |
|
||||
| A.java:35:16:35:16 | x | SSA init(x) | 0 | upper | NoReason |
|
||||
| A.java:35:16:35:16 | x | SSA init(y) | 1 | lower | ... == ... |
|
||||
| A.java:35:16:35:16 | x | SSA init(y) | 1 | upper | ... == ... |
|
||||
| A.java:35:16:35:16 | x | SSA init(z) | -1 | lower | ... == ... |
|
||||
| A.java:35:16:35:16 | x | SSA init(z) | -1 | upper | ... == ... |
|
||||
| A.java:35:16:35:16 | x | SSA param(x) | 0 | lower | NoReason |
|
||||
| A.java:35:16:35:16 | x | SSA param(x) | 0 | upper | NoReason |
|
||||
| A.java:35:16:35:16 | x | SSA param(y) | 1 | lower | ... == ... |
|
||||
| A.java:35:16:35:16 | x | SSA param(y) | 1 | upper | ... == ... |
|
||||
| A.java:35:16:35:16 | x | SSA param(z) | -1 | lower | ... == ... |
|
||||
| A.java:35:16:35:16 | x | SSA param(z) | -1 | upper | ... == ... |
|
||||
| A.java:35:16:35:20 | ... + ... | 0 | 697 | lower | ... == ... |
|
||||
| A.java:35:16:35:20 | ... + ... | 0 | 697 | upper | ... == ... |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA init(x) | 348 | lower | ... == ... |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA init(x) | 348 | lower | NoReason |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA init(x) | 348 | upper | ... == ... |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA init(x) | 348 | upper | NoReason |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA init(y) | 349 | lower | ... == ... |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA init(y) | 349 | lower | NoReason |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA init(y) | 349 | upper | ... == ... |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA init(y) | 349 | upper | NoReason |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA init(z) | 347 | lower | ... == ... |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA init(z) | 347 | upper | ... == ... |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA param(x) | 348 | lower | ... == ... |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA param(x) | 348 | lower | NoReason |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA param(x) | 348 | upper | ... == ... |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA param(x) | 348 | upper | NoReason |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA param(y) | 349 | lower | ... == ... |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA param(y) | 349 | lower | NoReason |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA param(y) | 349 | upper | ... == ... |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA param(y) | 349 | upper | NoReason |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA param(z) | 347 | lower | ... == ... |
|
||||
| A.java:35:16:35:20 | ... + ... | SSA param(z) | 347 | upper | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | 0 | 1047 | lower | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | 0 | 1047 | upper | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(x) | 698 | lower | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(x) | 698 | lower | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(x) | 698 | lower | NoReason |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(x) | 698 | upper | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(x) | 698 | upper | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(x) | 698 | upper | NoReason |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(y) | 699 | lower | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(y) | 699 | lower | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(y) | 699 | lower | NoReason |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(y) | 699 | upper | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(y) | 699 | upper | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(y) | 699 | upper | NoReason |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(z) | 697 | lower | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(z) | 697 | lower | NoReason |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(z) | 697 | upper | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA init(z) | 697 | upper | NoReason |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(x) | 698 | lower | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(x) | 698 | lower | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(x) | 698 | lower | NoReason |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(x) | 698 | upper | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(x) | 698 | upper | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(x) | 698 | upper | NoReason |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(y) | 699 | lower | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(y) | 699 | lower | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(y) | 699 | lower | NoReason |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(y) | 699 | upper | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(y) | 699 | upper | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(y) | 699 | upper | NoReason |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(z) | 697 | lower | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(z) | 697 | lower | NoReason |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(z) | 697 | upper | ... == ... |
|
||||
| A.java:35:16:35:24 | ... + ... | SSA param(z) | 697 | upper | NoReason |
|
||||
| A.java:35:20:35:20 | y | 0 | 348 | lower | ... == ... |
|
||||
| A.java:35:20:35:20 | y | 0 | 348 | upper | ... == ... |
|
||||
| A.java:35:20:35:20 | y | SSA init(x) | -1 | lower | ... == ... |
|
||||
| A.java:35:20:35:20 | y | SSA init(x) | -1 | upper | ... == ... |
|
||||
| A.java:35:20:35:20 | y | SSA init(y) | 0 | lower | NoReason |
|
||||
| A.java:35:20:35:20 | y | SSA init(y) | 0 | upper | NoReason |
|
||||
| A.java:35:20:35:20 | y | SSA init(z) | -2 | lower | ... == ... |
|
||||
| A.java:35:20:35:20 | y | SSA init(z) | -2 | upper | ... == ... |
|
||||
| A.java:35:20:35:20 | y | SSA param(x) | -1 | lower | ... == ... |
|
||||
| A.java:35:20:35:20 | y | SSA param(x) | -1 | upper | ... == ... |
|
||||
| A.java:35:20:35:20 | y | SSA param(y) | 0 | lower | NoReason |
|
||||
| A.java:35:20:35:20 | y | SSA param(y) | 0 | upper | NoReason |
|
||||
| A.java:35:20:35:20 | y | SSA param(z) | -2 | lower | ... == ... |
|
||||
| A.java:35:20:35:20 | y | SSA param(z) | -2 | upper | ... == ... |
|
||||
| A.java:35:24:35:24 | z | 0 | 350 | lower | ... == ... |
|
||||
| A.java:35:24:35:24 | z | 0 | 350 | upper | ... == ... |
|
||||
| A.java:35:24:35:24 | z | SSA init(x) | 1 | lower | ... == ... |
|
||||
| A.java:35:24:35:24 | z | SSA init(x) | 1 | upper | ... == ... |
|
||||
| A.java:35:24:35:24 | z | SSA init(y) | 2 | lower | ... == ... |
|
||||
| A.java:35:24:35:24 | z | SSA init(y) | 2 | upper | ... == ... |
|
||||
| A.java:35:24:35:24 | z | SSA init(z) | 0 | lower | NoReason |
|
||||
| A.java:35:24:35:24 | z | SSA init(z) | 0 | upper | NoReason |
|
||||
| A.java:35:24:35:24 | z | SSA param(x) | 1 | lower | ... == ... |
|
||||
| A.java:35:24:35:24 | z | SSA param(x) | 1 | upper | ... == ... |
|
||||
| A.java:35:24:35:24 | z | SSA param(y) | 2 | lower | ... == ... |
|
||||
| A.java:35:24:35:24 | z | SSA param(y) | 2 | upper | ... == ... |
|
||||
| A.java:35:24:35:24 | z | SSA param(z) | 0 | lower | NoReason |
|
||||
| A.java:35:24:35:24 | z | SSA param(z) | 0 | upper | NoReason |
|
||||
| A.java:39:12:39:12 | 0 | 0 | 0 | lower | NoReason |
|
||||
| A.java:39:12:39:12 | 0 | 0 | 0 | upper | NoReason |
|
||||
|
||||
@@ -3,6 +3,6 @@ import semmle.code.java.dataflow.SSA
|
||||
|
||||
from int uses, int live
|
||||
where
|
||||
uses = strictcount(SsaVariable ssa, VarRead use | use = ssa.getAUse()) and
|
||||
live = strictcount(SsaVariable ssa, BasicBlock b | ssa.isLiveAtEndOfBlock(b))
|
||||
uses = strictcount(SsaDefinition ssa, VarRead use | use = ssa.getARead()) and
|
||||
live = strictcount(SsaDefinition ssa, BasicBlock b | ssa.isLiveAtEndOfBlock(b))
|
||||
select uses, live
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
| Nested.java:8:29:8:57 | SSA init(next(..).p1) | Nested.java:4:34:10:3 | SSA init(p1) |
|
||||
| Nested.java:8:29:8:57 | SSA init(next(..).x1) | Nested.java:5:9:5:14 | SSA def(x1) |
|
||||
| Nested.java:16:22:16:34 | SSA init(getInt(..).obj) | Nested.java:15:12:15:29 | SSA def(obj) |
|
||||
| Nested.java:19:27:22:7 | SSA init(getInt(..).hash) | Nested.java:16:15:16:34 | SSA def(hash) |
|
||||
| Nested.java:19:27:22:7 | SSA init(getInt(..).x2) | Nested.java:17:9:17:15 | SSA def(x2) |
|
||||
| Nested.java:20:27:20:39 | SSA init(getInt(..).obj) | Nested.java:15:12:15:29 | SSA def(obj) |
|
||||
| Nested.java:30:23:30:36 | SSA init(getInt(..).obj2) | Nested.java:30:5:30:37 | SSA phi(obj2) |
|
||||
| Nested.java:37:20:37:25 | SSA init(getInt(..).x3) | Nested.java:36:7:36:12 | SSA def(x3) |
|
||||
| Nested.java:40:20:40:25 | SSA init(getInt(..).x3) | Nested.java:39:7:39:12 | SSA def(x3) |
|
||||
| Nested.java:8:29:8:57 | SSA capture def(next(..).p1) | Nested.java:4:34:10:3 | SSA param(p1) |
|
||||
| Nested.java:8:29:8:57 | SSA capture def(next(..).x1) | Nested.java:5:9:5:14 | SSA def(x1) |
|
||||
| Nested.java:16:22:16:34 | SSA capture def(getInt(..).obj) | Nested.java:15:12:15:29 | SSA def(obj) |
|
||||
| Nested.java:19:27:22:7 | SSA capture def(getInt(..).hash) | Nested.java:16:15:16:34 | SSA def(hash) |
|
||||
| Nested.java:19:27:22:7 | SSA capture def(getInt(..).x2) | Nested.java:17:9:17:15 | SSA def(x2) |
|
||||
| Nested.java:20:27:20:39 | SSA capture def(getInt(..).obj) | Nested.java:15:12:15:29 | SSA def(obj) |
|
||||
| Nested.java:30:23:30:36 | SSA capture def(getInt(..).obj2) | Nested.java:30:5:30:37 | SSA phi(obj2) |
|
||||
| Nested.java:37:20:37:25 | SSA capture def(getInt(..).x3) | Nested.java:36:7:36:12 | SSA def(x3) |
|
||||
| Nested.java:40:20:40:25 | SSA capture def(getInt(..).x3) | Nested.java:39:7:39:12 | SSA def(x3) |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.SSA
|
||||
|
||||
from SsaImplicitInit closure, SsaVariable captured
|
||||
from SsaCapturedDefinition closure, SsaDefinition captured
|
||||
where closure.captures(captured)
|
||||
select closure, captured
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
| Fields.java:12:19:21:3 | SSA init(this.xs) | Fields.java:13:15:13:16 | xs |
|
||||
| Fields.java:14:5:14:9 | SSA impl upd[nonlocal](this.xs) | Fields.java:15:9:15:10 | xs |
|
||||
| Fields.java:12:19:21:3 | SSA entry def(this.xs) | Fields.java:13:15:13:16 | xs |
|
||||
| Fields.java:14:5:14:9 | SSA call def(this.xs) | Fields.java:15:9:15:10 | xs |
|
||||
| Fields.java:15:5:15:10 | SSA def(x) | Fields.java:16:9:16:9 | x |
|
||||
| Fields.java:17:7:17:11 | SSA impl upd[nonlocal](this.xs) | Fields.java:18:9:18:15 | this.xs |
|
||||
| Fields.java:17:7:17:11 | SSA call def(this.xs) | Fields.java:18:9:18:15 | this.xs |
|
||||
| Fields.java:18:5:18:16 | SSA phi(this.xs) | Fields.java:18:9:18:15 | this.xs |
|
||||
| Fields.java:19:5:19:19 | SSA def(this.xs) | Fields.java:20:9:20:10 | xs |
|
||||
| Fields.java:23:19:49:3 | SSA init(Fields.stat) | Fields.java:27:15:27:18 | stat |
|
||||
| Fields.java:23:19:49:3 | SSA init(this.xs) | Fields.java:26:15:26:16 | xs |
|
||||
| Fields.java:23:19:49:3 | SSA entry def(Fields.stat) | Fields.java:27:15:27:18 | stat |
|
||||
| Fields.java:23:19:49:3 | SSA entry def(this.xs) | Fields.java:26:15:26:16 | xs |
|
||||
| Fields.java:24:12:24:27 | SSA def(f) | Fields.java:25:15:25:15 | f |
|
||||
| Fields.java:24:12:24:27 | SSA impl upd[explicit qualifier](f.xs) | Fields.java:25:15:25:18 | f.xs |
|
||||
| Fields.java:24:16:24:27 | SSA impl upd[nonlocal](Fields.stat) | Fields.java:27:15:27:18 | stat |
|
||||
| Fields.java:28:5:28:12 | SSA impl upd[nonlocal](Fields.stat) | Fields.java:31:9:31:12 | stat |
|
||||
| Fields.java:28:5:28:12 | SSA impl upd[nonlocal](f.xs) | Fields.java:29:9:29:12 | f.xs |
|
||||
| Fields.java:28:5:28:12 | SSA impl upd[nonlocal](this.xs) | Fields.java:30:9:30:10 | xs |
|
||||
| Fields.java:32:5:32:9 | SSA impl upd[nonlocal](Fields.stat) | Fields.java:35:9:35:12 | stat |
|
||||
| Fields.java:32:5:32:9 | SSA impl upd[nonlocal](f.xs) | Fields.java:33:9:33:12 | f.xs |
|
||||
| Fields.java:32:5:32:9 | SSA impl upd[nonlocal](this.xs) | Fields.java:34:9:34:10 | xs |
|
||||
| Fields.java:24:12:24:27 | SSA qualifier def(f.xs) | Fields.java:25:15:25:18 | f.xs |
|
||||
| Fields.java:24:16:24:27 | SSA call def(Fields.stat) | Fields.java:27:15:27:18 | stat |
|
||||
| Fields.java:28:5:28:12 | SSA call def(Fields.stat) | Fields.java:31:9:31:12 | stat |
|
||||
| Fields.java:28:5:28:12 | SSA call def(f.xs) | Fields.java:29:9:29:12 | f.xs |
|
||||
| Fields.java:28:5:28:12 | SSA call def(this.xs) | Fields.java:30:9:30:10 | xs |
|
||||
| Fields.java:32:5:32:9 | SSA call def(Fields.stat) | Fields.java:35:9:35:12 | stat |
|
||||
| Fields.java:32:5:32:9 | SSA call def(f.xs) | Fields.java:33:9:33:12 | f.xs |
|
||||
| Fields.java:32:5:32:9 | SSA call def(this.xs) | Fields.java:34:9:34:10 | xs |
|
||||
| Fields.java:36:5:36:19 | SSA def(this.xs) | Fields.java:38:9:38:10 | xs |
|
||||
| Fields.java:39:5:39:21 | SSA def(f.xs) | Fields.java:40:9:40:12 | f.xs |
|
||||
| Fields.java:41:5:41:10 | SSA def(z) | Fields.java:42:9:42:9 | z |
|
||||
| Fields.java:43:7:43:22 | SSA def(f) | Fields.java:44:9:44:9 | f |
|
||||
| Fields.java:43:7:43:22 | SSA impl upd[explicit qualifier](f.xs) | Fields.java:44:9:44:12 | f.xs |
|
||||
| Fields.java:43:11:43:22 | SSA impl upd[nonlocal](Fields.stat) | Fields.java:48:9:48:12 | stat |
|
||||
| Fields.java:43:7:43:22 | SSA qualifier def(f.xs) | Fields.java:44:9:44:12 | f.xs |
|
||||
| Fields.java:43:11:43:22 | SSA call def(Fields.stat) | Fields.java:48:9:48:12 | stat |
|
||||
| Fields.java:44:5:44:13 | SSA phi(Fields.stat) | Fields.java:48:9:48:12 | stat |
|
||||
| Fields.java:44:5:44:13 | SSA phi(f) | Fields.java:44:9:44:9 | f |
|
||||
| Fields.java:44:5:44:13 | SSA phi(f.xs) | Fields.java:44:9:44:12 | f.xs |
|
||||
| Fields.java:45:5:45:16 | SSA impl upd[nonlocal](Fields.stat) | Fields.java:48:9:48:12 | stat |
|
||||
| Nested.java:8:29:8:57 | SSA init(next(..).p1) | Nested.java:8:38:8:39 | p1 |
|
||||
| Nested.java:8:29:8:57 | SSA init(next(..).x1) | Nested.java:8:43:8:44 | x1 |
|
||||
| Nested.java:16:22:16:34 | SSA init(getInt(..).obj) | Nested.java:16:22:16:24 | obj |
|
||||
| Fields.java:45:5:45:16 | SSA call def(Fields.stat) | Fields.java:48:9:48:12 | stat |
|
||||
| Nested.java:8:29:8:57 | SSA capture def(next(..).p1) | Nested.java:8:38:8:39 | p1 |
|
||||
| Nested.java:8:29:8:57 | SSA capture def(next(..).x1) | Nested.java:8:43:8:44 | x1 |
|
||||
| Nested.java:16:22:16:34 | SSA capture def(getInt(..).obj) | Nested.java:16:22:16:24 | obj |
|
||||
| Nested.java:18:15:23:5 | SSA def(h2) | Nested.java:25:9:25:10 | h2 |
|
||||
| Nested.java:19:27:22:7 | SSA init(getInt(..).hash) | Nested.java:21:21:21:24 | hash |
|
||||
| Nested.java:19:27:22:7 | SSA init(getInt(..).x2) | Nested.java:21:16:21:17 | x2 |
|
||||
| Nested.java:19:27:22:7 | SSA capture def(getInt(..).hash) | Nested.java:21:21:21:24 | hash |
|
||||
| Nested.java:19:27:22:7 | SSA capture def(getInt(..).x2) | Nested.java:21:16:21:17 | x2 |
|
||||
| Nested.java:20:19:20:39 | SSA def(hnest) | Nested.java:21:37:21:41 | hnest |
|
||||
| Nested.java:20:27:20:39 | SSA init(getInt(..).obj) | Nested.java:20:27:20:29 | obj |
|
||||
| Nested.java:30:23:30:36 | SSA init(getInt(..).obj2) | Nested.java:30:23:30:26 | obj2 |
|
||||
| Nested.java:33:29:42:3 | SSA init(p3) | Nested.java:35:9:35:10 | p3 |
|
||||
| Nested.java:37:20:37:25 | SSA init(getInt(..).x3) | Nested.java:37:20:37:21 | x3 |
|
||||
| Nested.java:40:20:40:25 | SSA init(getInt(..).x3) | Nested.java:40:20:40:21 | x3 |
|
||||
| Test.java:4:19:32:2 | SSA init(param) | Test.java:9:7:9:11 | param |
|
||||
| Nested.java:20:27:20:39 | SSA capture def(getInt(..).obj) | Nested.java:20:27:20:29 | obj |
|
||||
| Nested.java:30:23:30:36 | SSA capture def(getInt(..).obj2) | Nested.java:30:23:30:26 | obj2 |
|
||||
| Nested.java:33:29:42:3 | SSA param(p3) | Nested.java:35:9:35:10 | p3 |
|
||||
| Nested.java:37:20:37:25 | SSA capture def(getInt(..).x3) | Nested.java:37:20:37:21 | x3 |
|
||||
| Nested.java:40:20:40:25 | SSA capture def(getInt(..).x3) | Nested.java:40:20:40:21 | x3 |
|
||||
| Test.java:4:19:32:2 | SSA param(param) | Test.java:9:7:9:11 | param |
|
||||
| Test.java:6:7:6:11 | SSA def(x) | Test.java:10:4:10:4 | x |
|
||||
| Test.java:6:7:6:11 | SSA def(x) | Test.java:20:10:20:10 | x |
|
||||
| Test.java:10:4:10:6 | SSA def(x) | Test.java:11:10:11:10 | x |
|
||||
@@ -58,15 +58,12 @@
|
||||
| Test.java:27:25:27:27 | SSA def(i) | Test.java:27:19:27:19 | i |
|
||||
| Test.java:28:4:28:9 | SSA def(x) | Test.java:28:4:28:4 | x |
|
||||
| Test.java:28:4:28:9 | SSA def(x) | Test.java:31:10:31:10 | x |
|
||||
| TestInstanceOfPattern.java:3:24:9:2 | SSA init(obj) | TestInstanceOfPattern.java:4:7:4:9 | obj |
|
||||
| TestInstanceOfPattern.java:3:24:9:2 | SSA param(obj) | TestInstanceOfPattern.java:4:7:4:9 | obj |
|
||||
| TestInstanceOfPattern.java:4:29:4:29 | SSA def(s) | TestInstanceOfPattern.java:5:8:5:8 | s |
|
||||
| TestInstanceOfPattern.java:7:8:7:8 | SSA impl upd[untracked](this.s) | TestInstanceOfPattern.java:7:8:7:8 | s |
|
||||
| TestInstanceOfPattern.java:10:25:16:2 | SSA init(obj) | TestInstanceOfPattern.java:11:9:11:11 | obj |
|
||||
| TestInstanceOfPattern.java:10:25:16:2 | SSA param(obj) | TestInstanceOfPattern.java:11:9:11:11 | obj |
|
||||
| TestInstanceOfPattern.java:11:31:11:31 | SSA def(s) | TestInstanceOfPattern.java:14:8:14:8 | s |
|
||||
| TestInstanceOfPattern.java:12:8:12:8 | SSA impl upd[untracked](this.s) | TestInstanceOfPattern.java:12:8:12:8 | s |
|
||||
| TestInstanceOfPattern.java:17:25:23:2 | SSA init(obj) | TestInstanceOfPattern.java:18:7:18:9 | obj |
|
||||
| TestInstanceOfPattern.java:17:25:23:2 | SSA param(obj) | TestInstanceOfPattern.java:18:7:18:9 | obj |
|
||||
| TestInstanceOfPattern.java:18:29:18:29 | SSA def(s) | TestInstanceOfPattern.java:18:34:18:34 | s |
|
||||
| TestInstanceOfPattern.java:21:8:21:8 | SSA impl upd[untracked](this.s) | TestInstanceOfPattern.java:21:8:21:8 | s |
|
||||
| TestInstanceOfPattern.java:24:25:30:2 | SSA init(obj) | TestInstanceOfPattern.java:25:7:25:9 | obj |
|
||||
| TestInstanceOfPattern.java:24:25:30:2 | SSA init(this.s) | TestInstanceOfPattern.java:25:34:25:34 | s |
|
||||
| TestInstanceOfPattern.java:24:25:30:2 | SSA init(this.s) | TestInstanceOfPattern.java:26:8:26:8 | s |
|
||||
| TestInstanceOfPattern.java:24:25:30:2 | SSA entry def(this.s) | TestInstanceOfPattern.java:25:34:25:34 | s |
|
||||
| TestInstanceOfPattern.java:24:25:30:2 | SSA entry def(this.s) | TestInstanceOfPattern.java:26:8:26:8 | s |
|
||||
| TestInstanceOfPattern.java:24:25:30:2 | SSA param(obj) | TestInstanceOfPattern.java:25:7:25:9 | obj |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.SSA
|
||||
|
||||
from SsaVariable ssa, VarRead use
|
||||
where use = ssa.getAFirstUse()
|
||||
from SsaDefinition ssa, VarRead use
|
||||
where use = ssaGetAFirstUse(ssa)
|
||||
select ssa, use
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
| Fields.java:13:5:13:17 | x | Fields.java:15:5:15:10 | ...=... | SSA def(x) |
|
||||
| Fields.java:13:15:13:16 | this.xs | Fields.java:12:19:21:3 | { ... } | SSA init(this.xs) |
|
||||
| Fields.java:13:15:13:16 | this.xs | Fields.java:14:5:14:9 | upd(...) | SSA impl upd[nonlocal](this.xs) |
|
||||
| Fields.java:13:15:13:16 | this.xs | Fields.java:17:7:17:11 | upd(...) | SSA impl upd[nonlocal](this.xs) |
|
||||
| Fields.java:13:15:13:16 | this.xs | Fields.java:12:19:21:3 | { ... } | SSA entry def(this.xs) |
|
||||
| Fields.java:13:15:13:16 | this.xs | Fields.java:14:5:14:9 | upd(...) | SSA call def(this.xs) |
|
||||
| Fields.java:13:15:13:16 | this.xs | Fields.java:17:7:17:11 | upd(...) | SSA call def(this.xs) |
|
||||
| Fields.java:13:15:13:16 | this.xs | Fields.java:18:5:18:16 | <Expr>; | SSA phi(this.xs) |
|
||||
| Fields.java:13:15:13:16 | this.xs | Fields.java:19:5:19:19 | ...=... | SSA def(this.xs) |
|
||||
| Fields.java:24:5:24:28 | f | Fields.java:24:12:24:27 | f | SSA def(f) |
|
||||
| Fields.java:24:5:24:28 | f | Fields.java:43:7:43:22 | ...=... | SSA def(f) |
|
||||
| Fields.java:24:5:24:28 | f | Fields.java:44:5:44:13 | <Expr>; | SSA phi(f) |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:24:12:24:27 | f | SSA impl upd[explicit qualifier](f.xs) |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:28:5:28:12 | f(...) | SSA impl upd[nonlocal](f.xs) |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:32:5:32:9 | f(...) | SSA impl upd[nonlocal](f.xs) |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:24:12:24:27 | f | SSA qualifier def(f.xs) |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:28:5:28:12 | f(...) | SSA call def(f.xs) |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:32:5:32:9 | f(...) | SSA call def(f.xs) |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:39:5:39:21 | ...=... | SSA def(f.xs) |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:43:7:43:22 | ...=... | SSA impl upd[explicit qualifier](f.xs) |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:43:7:43:22 | ...=... | SSA qualifier def(f.xs) |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:44:5:44:13 | <Expr>; | SSA phi(f.xs) |
|
||||
| Fields.java:26:5:26:17 | z | Fields.java:41:5:41:10 | ...=... | SSA def(z) |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:23:19:49:3 | { ... } | SSA init(this.xs) |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:28:5:28:12 | f(...) | SSA impl upd[nonlocal](this.xs) |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:32:5:32:9 | f(...) | SSA impl upd[nonlocal](this.xs) |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:23:19:49:3 | { ... } | SSA entry def(this.xs) |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:28:5:28:12 | f(...) | SSA call def(this.xs) |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:32:5:32:9 | f(...) | SSA call def(this.xs) |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:36:5:36:19 | ...=... | SSA def(this.xs) |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:23:19:49:3 | { ... } | SSA init(Fields.stat) |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:24:16:24:27 | new Fields(...) | SSA impl upd[nonlocal](Fields.stat) |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:28:5:28:12 | f(...) | SSA impl upd[nonlocal](Fields.stat) |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:32:5:32:9 | f(...) | SSA impl upd[nonlocal](Fields.stat) |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:43:11:43:22 | new Fields(...) | SSA impl upd[nonlocal](Fields.stat) |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:23:19:49:3 | { ... } | SSA entry def(Fields.stat) |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:24:16:24:27 | new Fields(...) | SSA call def(Fields.stat) |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:28:5:28:12 | f(...) | SSA call def(Fields.stat) |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:32:5:32:9 | f(...) | SSA call def(Fields.stat) |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:43:11:43:22 | new Fields(...) | SSA call def(Fields.stat) |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:44:5:44:13 | <Expr>; | SSA phi(Fields.stat) |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:45:5:45:16 | new Fields(...) | SSA impl upd[nonlocal](Fields.stat) |
|
||||
| Nested.java:4:26:4:31 | next(..).p1 | Nested.java:8:29:8:57 | { ... } | SSA init(next(..).p1) |
|
||||
| Nested.java:4:26:4:31 | p1 | Nested.java:4:34:10:3 | { ... } | SSA init(p1) |
|
||||
| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | { ... } | SSA init(next(..).x1) |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:45:5:45:16 | new Fields(...) | SSA call def(Fields.stat) |
|
||||
| Nested.java:4:26:4:31 | next(..).p1 | Nested.java:8:29:8:57 | { ... } | SSA capture def(next(..).p1) |
|
||||
| Nested.java:4:26:4:31 | p1 | Nested.java:4:34:10:3 | { ... } | SSA param(p1) |
|
||||
| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | { ... } | SSA capture def(next(..).x1) |
|
||||
| Nested.java:5:5:5:15 | x1 | Nested.java:5:9:5:14 | x1 | SSA def(x1) |
|
||||
| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:16:22:16:34 | { ... } | SSA init(getInt(..).obj) |
|
||||
| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:20:27:20:39 | { ... } | SSA init(getInt(..).obj) |
|
||||
| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:16:22:16:34 | { ... } | SSA capture def(getInt(..).obj) |
|
||||
| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:20:27:20:39 | { ... } | SSA capture def(getInt(..).obj) |
|
||||
| Nested.java:15:5:15:30 | obj | Nested.java:15:12:15:29 | obj | SSA def(obj) |
|
||||
| Nested.java:16:5:16:35 | getInt(..).hash | Nested.java:19:27:22:7 | { ... } | SSA init(getInt(..).hash) |
|
||||
| Nested.java:16:5:16:35 | getInt(..).hash | Nested.java:19:27:22:7 | { ... } | SSA capture def(getInt(..).hash) |
|
||||
| Nested.java:16:5:16:35 | hash | Nested.java:16:15:16:34 | hash | SSA def(hash) |
|
||||
| Nested.java:17:5:17:16 | getInt(..).x2 | Nested.java:19:27:22:7 | { ... } | SSA init(getInt(..).x2) |
|
||||
| Nested.java:17:5:17:16 | getInt(..).x2 | Nested.java:19:27:22:7 | { ... } | SSA capture def(getInt(..).x2) |
|
||||
| Nested.java:17:5:17:16 | x2 | Nested.java:17:9:17:15 | x2 | SSA def(x2) |
|
||||
| Nested.java:18:5:23:6 | h2 | Nested.java:18:15:23:5 | h2 | SSA def(h2) |
|
||||
| Nested.java:20:9:20:40 | hnest | Nested.java:20:19:20:39 | hnest | SSA def(hnest) |
|
||||
| Nested.java:24:5:24:31 | getInt(..).obj2 | Nested.java:30:23:30:36 | { ... } | SSA init(getInt(..).obj2) |
|
||||
| Nested.java:24:5:24:31 | getInt(..).obj2 | Nested.java:30:23:30:36 | { ... } | SSA capture def(getInt(..).obj2) |
|
||||
| Nested.java:24:5:24:31 | obj2 | Nested.java:26:7:26:25 | ...=... | SSA def(obj2) |
|
||||
| Nested.java:24:5:24:31 | obj2 | Nested.java:28:7:28:25 | ...=... | SSA def(obj2) |
|
||||
| Nested.java:24:5:24:31 | obj2 | Nested.java:30:5:30:37 | var ...; | SSA phi(obj2) |
|
||||
| Nested.java:33:21:33:26 | p3 | Nested.java:33:29:42:3 | { ... } | SSA init(p3) |
|
||||
| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:37:20:37:25 | { ... } | SSA init(getInt(..).x3) |
|
||||
| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:40:20:40:25 | { ... } | SSA init(getInt(..).x3) |
|
||||
| Nested.java:33:21:33:26 | p3 | Nested.java:33:29:42:3 | { ... } | SSA param(p3) |
|
||||
| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:37:20:37:25 | { ... } | SSA capture def(getInt(..).x3) |
|
||||
| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:40:20:40:25 | { ... } | SSA capture def(getInt(..).x3) |
|
||||
| Nested.java:34:5:34:11 | x3 | Nested.java:36:7:36:12 | ...=... | SSA def(x3) |
|
||||
| Nested.java:34:5:34:11 | x3 | Nested.java:39:7:39:12 | ...=... | SSA def(x3) |
|
||||
| Test.java:4:8:4:16 | param | Test.java:4:19:32:2 | { ... } | SSA init(param) |
|
||||
| Test.java:4:8:4:16 | param | Test.java:4:19:32:2 | { ... } | SSA param(param) |
|
||||
| Test.java:4:8:4:16 | param | Test.java:20:10:20:10 | x | SSA phi(param) |
|
||||
| Test.java:4:8:4:16 | param | Test.java:21:8:21:14 | ...++ | SSA def(param) |
|
||||
| Test.java:6:3:6:12 | x | Test.java:6:7:6:11 | x | SSA def(x) |
|
||||
@@ -65,14 +65,11 @@
|
||||
| Test.java:27:8:27:16 | i | Test.java:27:12:27:16 | i | SSA def(i) |
|
||||
| Test.java:27:8:27:16 | i | Test.java:27:19:27:19 | i | SSA phi(i) |
|
||||
| Test.java:27:8:27:16 | i | Test.java:27:25:27:27 | ...++ | SSA def(i) |
|
||||
| TestInstanceOfPattern.java:3:12:3:21 | obj | TestInstanceOfPattern.java:3:24:9:2 | { ... } | SSA init(obj) |
|
||||
| TestInstanceOfPattern.java:3:12:3:21 | obj | TestInstanceOfPattern.java:3:24:9:2 | { ... } | SSA param(obj) |
|
||||
| TestInstanceOfPattern.java:4:22:4:29 | s | TestInstanceOfPattern.java:4:29:4:29 | s | SSA def(s) |
|
||||
| TestInstanceOfPattern.java:7:8:7:8 | this.s | TestInstanceOfPattern.java:7:8:7:8 | s | SSA impl upd[untracked](this.s) |
|
||||
| TestInstanceOfPattern.java:10:13:10:22 | obj | TestInstanceOfPattern.java:10:25:16:2 | { ... } | SSA init(obj) |
|
||||
| TestInstanceOfPattern.java:10:13:10:22 | obj | TestInstanceOfPattern.java:10:25:16:2 | { ... } | SSA param(obj) |
|
||||
| TestInstanceOfPattern.java:11:24:11:31 | s | TestInstanceOfPattern.java:11:31:11:31 | s | SSA def(s) |
|
||||
| TestInstanceOfPattern.java:12:8:12:8 | this.s | TestInstanceOfPattern.java:12:8:12:8 | s | SSA impl upd[untracked](this.s) |
|
||||
| TestInstanceOfPattern.java:17:13:17:22 | obj | TestInstanceOfPattern.java:17:25:23:2 | { ... } | SSA init(obj) |
|
||||
| TestInstanceOfPattern.java:17:13:17:22 | obj | TestInstanceOfPattern.java:17:25:23:2 | { ... } | SSA param(obj) |
|
||||
| TestInstanceOfPattern.java:18:22:18:29 | s | TestInstanceOfPattern.java:18:29:18:29 | s | SSA def(s) |
|
||||
| TestInstanceOfPattern.java:21:8:21:8 | this.s | TestInstanceOfPattern.java:21:8:21:8 | s | SSA impl upd[untracked](this.s) |
|
||||
| TestInstanceOfPattern.java:24:13:24:22 | obj | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA init(obj) |
|
||||
| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA init(this.s) |
|
||||
| TestInstanceOfPattern.java:24:13:24:22 | obj | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA param(obj) |
|
||||
| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA entry def(this.s) |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.SSA
|
||||
|
||||
from SsaVariable ssa, SsaSourceVariable v, string s
|
||||
from SsaDefinition ssa, SsaSourceVariable v, string s
|
||||
where
|
||||
ssa.getSourceVariable() = v and
|
||||
(
|
||||
@@ -9,4 +9,4 @@ where
|
||||
or
|
||||
not exists(ssa.toString()) and s = "error"
|
||||
)
|
||||
select v, ssa.getCfgNode(), s
|
||||
select v, ssa.getControlFlowNode(), s
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.SSA
|
||||
|
||||
from SsaPhiNode ssa, SsaSourceVariable v, SsaVariable phiInput
|
||||
where ssa.getAPhiInput() = phiInput and ssa.getSourceVariable() = v
|
||||
select v, ssa.getCfgNode(), phiInput.getCfgNode()
|
||||
from SsaPhiDefinition ssa, SsaSourceVariable v, SsaDefinition phiInput
|
||||
where ssa.getAnInput() = phiInput and ssa.getSourceVariable() = v
|
||||
select v, ssa.getControlFlowNode(), phiInput.getControlFlowNode()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
| Fields.java:13:5:13:17 | x | Fields.java:15:5:15:10 | ...=... | SSA def(x) | Fields.java:16:9:16:9 | x |
|
||||
| Fields.java:13:15:13:16 | this.xs | Fields.java:12:19:21:3 | { ... } | SSA init(this.xs) | Fields.java:13:15:13:16 | xs |
|
||||
| Fields.java:13:15:13:16 | this.xs | Fields.java:14:5:14:9 | upd(...) | SSA impl upd[nonlocal](this.xs) | Fields.java:15:9:15:10 | xs |
|
||||
| Fields.java:13:15:13:16 | this.xs | Fields.java:12:19:21:3 | { ... } | SSA entry def(this.xs) | Fields.java:13:15:13:16 | xs |
|
||||
| Fields.java:13:15:13:16 | this.xs | Fields.java:14:5:14:9 | upd(...) | SSA call def(this.xs) | Fields.java:15:9:15:10 | xs |
|
||||
| Fields.java:13:15:13:16 | this.xs | Fields.java:18:5:18:16 | <Expr>; | SSA phi(this.xs) | Fields.java:18:9:18:15 | this.xs |
|
||||
| Fields.java:13:15:13:16 | this.xs | Fields.java:19:5:19:19 | ...=... | SSA def(this.xs) | Fields.java:20:9:20:10 | xs |
|
||||
| Fields.java:24:5:24:28 | f | Fields.java:24:12:24:27 | f | SSA def(f) | Fields.java:25:15:25:15 | f |
|
||||
@@ -12,39 +12,39 @@
|
||||
| Fields.java:24:5:24:28 | f | Fields.java:24:12:24:27 | f | SSA def(f) | Fields.java:40:9:40:9 | f |
|
||||
| Fields.java:24:5:24:28 | f | Fields.java:44:5:44:13 | <Expr>; | SSA phi(f) | Fields.java:44:9:44:9 | f |
|
||||
| Fields.java:24:5:24:28 | f | Fields.java:44:5:44:13 | <Expr>; | SSA phi(f) | Fields.java:46:9:46:9 | f |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:24:12:24:27 | f | SSA impl upd[explicit qualifier](f.xs) | Fields.java:25:15:25:18 | f.xs |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:28:5:28:12 | f(...) | SSA impl upd[nonlocal](f.xs) | Fields.java:29:9:29:12 | f.xs |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:32:5:32:9 | f(...) | SSA impl upd[nonlocal](f.xs) | Fields.java:33:9:33:12 | f.xs |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:32:5:32:9 | f(...) | SSA impl upd[nonlocal](f.xs) | Fields.java:37:9:37:12 | f.xs |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:24:12:24:27 | f | SSA qualifier def(f.xs) | Fields.java:25:15:25:18 | f.xs |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:28:5:28:12 | f(...) | SSA call def(f.xs) | Fields.java:29:9:29:12 | f.xs |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:32:5:32:9 | f(...) | SSA call def(f.xs) | Fields.java:33:9:33:12 | f.xs |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:32:5:32:9 | f(...) | SSA call def(f.xs) | Fields.java:37:9:37:12 | f.xs |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:39:5:39:21 | ...=... | SSA def(f.xs) | Fields.java:40:9:40:12 | f.xs |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:44:5:44:13 | <Expr>; | SSA phi(f.xs) | Fields.java:44:9:44:12 | f.xs |
|
||||
| Fields.java:25:15:25:18 | f.xs | Fields.java:44:5:44:13 | <Expr>; | SSA phi(f.xs) | Fields.java:46:9:46:12 | f.xs |
|
||||
| Fields.java:26:5:26:17 | z | Fields.java:41:5:41:10 | ...=... | SSA def(z) | Fields.java:42:9:42:9 | z |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:23:19:49:3 | { ... } | SSA init(this.xs) | Fields.java:26:15:26:16 | xs |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:28:5:28:12 | f(...) | SSA impl upd[nonlocal](this.xs) | Fields.java:30:9:30:10 | xs |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:32:5:32:9 | f(...) | SSA impl upd[nonlocal](this.xs) | Fields.java:34:9:34:10 | xs |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:23:19:49:3 | { ... } | SSA entry def(this.xs) | Fields.java:26:15:26:16 | xs |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:28:5:28:12 | f(...) | SSA call def(this.xs) | Fields.java:30:9:30:10 | xs |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:32:5:32:9 | f(...) | SSA call def(this.xs) | Fields.java:34:9:34:10 | xs |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:36:5:36:19 | ...=... | SSA def(this.xs) | Fields.java:38:9:38:10 | xs |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:36:5:36:19 | ...=... | SSA def(this.xs) | Fields.java:41:9:41:10 | xs |
|
||||
| Fields.java:26:15:26:16 | this.xs | Fields.java:36:5:36:19 | ...=... | SSA def(this.xs) | Fields.java:47:9:47:10 | xs |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:24:16:24:27 | new Fields(...) | SSA impl upd[nonlocal](Fields.stat) | Fields.java:27:15:27:18 | stat |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:28:5:28:12 | f(...) | SSA impl upd[nonlocal](Fields.stat) | Fields.java:31:9:31:12 | stat |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:32:5:32:9 | f(...) | SSA impl upd[nonlocal](Fields.stat) | Fields.java:35:9:35:12 | stat |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:45:5:45:16 | new Fields(...) | SSA impl upd[nonlocal](Fields.stat) | Fields.java:48:9:48:12 | stat |
|
||||
| Nested.java:4:26:4:31 | next(..).p1 | Nested.java:8:29:8:57 | { ... } | SSA init(next(..).p1) | Nested.java:8:38:8:39 | p1 |
|
||||
| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | { ... } | SSA init(next(..).x1) | Nested.java:8:43:8:44 | x1 |
|
||||
| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | { ... } | SSA init(next(..).x1) | Nested.java:8:48:8:49 | x1 |
|
||||
| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | { ... } | SSA init(next(..).x1) | Nested.java:8:53:8:54 | x1 |
|
||||
| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:16:22:16:34 | { ... } | SSA init(getInt(..).obj) | Nested.java:16:22:16:24 | obj |
|
||||
| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:20:27:20:39 | { ... } | SSA init(getInt(..).obj) | Nested.java:20:27:20:29 | obj |
|
||||
| Nested.java:16:5:16:35 | getInt(..).hash | Nested.java:19:27:22:7 | { ... } | SSA init(getInt(..).hash) | Nested.java:21:21:21:24 | hash |
|
||||
| Nested.java:17:5:17:16 | getInt(..).x2 | Nested.java:19:27:22:7 | { ... } | SSA init(getInt(..).x2) | Nested.java:21:16:21:17 | x2 |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:24:16:24:27 | new Fields(...) | SSA call def(Fields.stat) | Fields.java:27:15:27:18 | stat |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:28:5:28:12 | f(...) | SSA call def(Fields.stat) | Fields.java:31:9:31:12 | stat |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:32:5:32:9 | f(...) | SSA call def(Fields.stat) | Fields.java:35:9:35:12 | stat |
|
||||
| Fields.java:27:15:27:18 | Fields.stat | Fields.java:45:5:45:16 | new Fields(...) | SSA call def(Fields.stat) | Fields.java:48:9:48:12 | stat |
|
||||
| Nested.java:4:26:4:31 | next(..).p1 | Nested.java:8:29:8:57 | { ... } | SSA capture def(next(..).p1) | Nested.java:8:38:8:39 | p1 |
|
||||
| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | { ... } | SSA capture def(next(..).x1) | Nested.java:8:43:8:44 | x1 |
|
||||
| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | { ... } | SSA capture def(next(..).x1) | Nested.java:8:48:8:49 | x1 |
|
||||
| Nested.java:5:5:5:15 | next(..).x1 | Nested.java:8:29:8:57 | { ... } | SSA capture def(next(..).x1) | Nested.java:8:53:8:54 | x1 |
|
||||
| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:16:22:16:34 | { ... } | SSA capture def(getInt(..).obj) | Nested.java:16:22:16:24 | obj |
|
||||
| Nested.java:15:5:15:30 | getInt(..).obj | Nested.java:20:27:20:39 | { ... } | SSA capture def(getInt(..).obj) | Nested.java:20:27:20:29 | obj |
|
||||
| Nested.java:16:5:16:35 | getInt(..).hash | Nested.java:19:27:22:7 | { ... } | SSA capture def(getInt(..).hash) | Nested.java:21:21:21:24 | hash |
|
||||
| Nested.java:17:5:17:16 | getInt(..).x2 | Nested.java:19:27:22:7 | { ... } | SSA capture def(getInt(..).x2) | Nested.java:21:16:21:17 | x2 |
|
||||
| Nested.java:18:5:23:6 | h2 | Nested.java:18:15:23:5 | h2 | SSA def(h2) | Nested.java:25:9:25:10 | h2 |
|
||||
| Nested.java:20:9:20:40 | hnest | Nested.java:20:19:20:39 | hnest | SSA def(hnest) | Nested.java:21:37:21:41 | hnest |
|
||||
| Nested.java:24:5:24:31 | getInt(..).obj2 | Nested.java:30:23:30:36 | { ... } | SSA init(getInt(..).obj2) | Nested.java:30:23:30:26 | obj2 |
|
||||
| Nested.java:33:21:33:26 | p3 | Nested.java:33:29:42:3 | { ... } | SSA init(p3) | Nested.java:35:9:35:10 | p3 |
|
||||
| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:37:20:37:25 | { ... } | SSA init(getInt(..).x3) | Nested.java:37:20:37:21 | x3 |
|
||||
| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:40:20:40:25 | { ... } | SSA init(getInt(..).x3) | Nested.java:40:20:40:21 | x3 |
|
||||
| Test.java:4:8:4:16 | param | Test.java:4:19:32:2 | { ... } | SSA init(param) | Test.java:9:7:9:11 | param |
|
||||
| Nested.java:24:5:24:31 | getInt(..).obj2 | Nested.java:30:23:30:36 | { ... } | SSA capture def(getInt(..).obj2) | Nested.java:30:23:30:26 | obj2 |
|
||||
| Nested.java:33:21:33:26 | p3 | Nested.java:33:29:42:3 | { ... } | SSA param(p3) | Nested.java:35:9:35:10 | p3 |
|
||||
| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:37:20:37:25 | { ... } | SSA capture def(getInt(..).x3) | Nested.java:37:20:37:21 | x3 |
|
||||
| Nested.java:34:5:34:11 | getInt(..).x3 | Nested.java:40:20:40:25 | { ... } | SSA capture def(getInt(..).x3) | Nested.java:40:20:40:21 | x3 |
|
||||
| Test.java:4:8:4:16 | param | Test.java:4:19:32:2 | { ... } | SSA param(param) | Test.java:9:7:9:11 | param |
|
||||
| Test.java:4:8:4:16 | param | Test.java:20:10:20:10 | x | SSA phi(param) | Test.java:21:8:21:12 | param |
|
||||
| Test.java:6:3:6:12 | x | Test.java:6:7:6:11 | x | SSA def(x) | Test.java:10:4:10:4 | x |
|
||||
| Test.java:6:3:6:12 | x | Test.java:10:4:10:6 | ...++ | SSA def(x) | Test.java:11:10:11:10 | x |
|
||||
@@ -58,17 +58,14 @@
|
||||
| Test.java:27:8:27:16 | i | Test.java:27:19:27:19 | i | SSA phi(i) | Test.java:27:19:27:19 | i |
|
||||
| Test.java:27:8:27:16 | i | Test.java:27:19:27:19 | i | SSA phi(i) | Test.java:27:25:27:25 | i |
|
||||
| Test.java:27:8:27:16 | i | Test.java:27:19:27:19 | i | SSA phi(i) | Test.java:28:9:28:9 | i |
|
||||
| TestInstanceOfPattern.java:3:12:3:21 | obj | TestInstanceOfPattern.java:3:24:9:2 | { ... } | SSA init(obj) | TestInstanceOfPattern.java:4:7:4:9 | obj |
|
||||
| TestInstanceOfPattern.java:3:12:3:21 | obj | TestInstanceOfPattern.java:3:24:9:2 | { ... } | SSA param(obj) | TestInstanceOfPattern.java:4:7:4:9 | obj |
|
||||
| TestInstanceOfPattern.java:4:22:4:29 | s | TestInstanceOfPattern.java:4:29:4:29 | s | SSA def(s) | TestInstanceOfPattern.java:5:8:5:8 | s |
|
||||
| TestInstanceOfPattern.java:7:8:7:8 | this.s | TestInstanceOfPattern.java:7:8:7:8 | s | SSA impl upd[untracked](this.s) | TestInstanceOfPattern.java:7:8:7:8 | s |
|
||||
| TestInstanceOfPattern.java:10:13:10:22 | obj | TestInstanceOfPattern.java:10:25:16:2 | { ... } | SSA init(obj) | TestInstanceOfPattern.java:11:9:11:11 | obj |
|
||||
| TestInstanceOfPattern.java:10:13:10:22 | obj | TestInstanceOfPattern.java:10:25:16:2 | { ... } | SSA param(obj) | TestInstanceOfPattern.java:11:9:11:11 | obj |
|
||||
| TestInstanceOfPattern.java:11:24:11:31 | s | TestInstanceOfPattern.java:11:31:11:31 | s | SSA def(s) | TestInstanceOfPattern.java:14:8:14:8 | s |
|
||||
| TestInstanceOfPattern.java:12:8:12:8 | this.s | TestInstanceOfPattern.java:12:8:12:8 | s | SSA impl upd[untracked](this.s) | TestInstanceOfPattern.java:12:8:12:8 | s |
|
||||
| TestInstanceOfPattern.java:17:13:17:22 | obj | TestInstanceOfPattern.java:17:25:23:2 | { ... } | SSA init(obj) | TestInstanceOfPattern.java:18:7:18:9 | obj |
|
||||
| TestInstanceOfPattern.java:17:13:17:22 | obj | TestInstanceOfPattern.java:17:25:23:2 | { ... } | SSA param(obj) | TestInstanceOfPattern.java:18:7:18:9 | obj |
|
||||
| TestInstanceOfPattern.java:18:22:18:29 | s | TestInstanceOfPattern.java:18:29:18:29 | s | SSA def(s) | TestInstanceOfPattern.java:18:34:18:34 | s |
|
||||
| TestInstanceOfPattern.java:18:22:18:29 | s | TestInstanceOfPattern.java:18:29:18:29 | s | SSA def(s) | TestInstanceOfPattern.java:19:8:19:8 | s |
|
||||
| TestInstanceOfPattern.java:21:8:21:8 | this.s | TestInstanceOfPattern.java:21:8:21:8 | s | SSA impl upd[untracked](this.s) | TestInstanceOfPattern.java:21:8:21:8 | s |
|
||||
| TestInstanceOfPattern.java:24:13:24:22 | obj | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA init(obj) | TestInstanceOfPattern.java:25:7:25:9 | obj |
|
||||
| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA init(this.s) | TestInstanceOfPattern.java:25:34:25:34 | s |
|
||||
| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA init(this.s) | TestInstanceOfPattern.java:26:8:26:8 | s |
|
||||
| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA init(this.s) | TestInstanceOfPattern.java:28:8:28:8 | s |
|
||||
| TestInstanceOfPattern.java:24:13:24:22 | obj | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA param(obj) | TestInstanceOfPattern.java:25:7:25:9 | obj |
|
||||
| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA entry def(this.s) | TestInstanceOfPattern.java:25:34:25:34 | s |
|
||||
| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA entry def(this.s) | TestInstanceOfPattern.java:26:8:26:8 | s |
|
||||
| TestInstanceOfPattern.java:25:34:25:34 | this.s | TestInstanceOfPattern.java:24:25:30:2 | { ... } | SSA entry def(this.s) | TestInstanceOfPattern.java:28:8:28:8 | s |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.SSA
|
||||
|
||||
from SsaVariable ssa, SsaSourceVariable v, Expr use
|
||||
where use = ssa.getAUse() and ssa.getSourceVariable() = v
|
||||
select v, ssa.getCfgNode(), ssa.toString(), use
|
||||
from SsaDefinition ssa, SsaSourceVariable v, Expr use
|
||||
where use = ssa.getARead() and ssa.getSourceVariable() = v
|
||||
select v, ssa.getControlFlowNode(), ssa.toString(), use
|
||||
|
||||
BIN
misc/ripunzip/ripunzip-Linux.tar.zst
(Stored with Git LFS)
BIN
misc/ripunzip/ripunzip-Linux.tar.zst
(Stored with Git LFS)
Binary file not shown.
BIN
misc/ripunzip/ripunzip-Windows.tar.zst
(Stored with Git LFS)
BIN
misc/ripunzip/ripunzip-Windows.tar.zst
(Stored with Git LFS)
Binary file not shown.
BIN
misc/ripunzip/ripunzip-macOS.tar.zst
(Stored with Git LFS)
BIN
misc/ripunzip/ripunzip-macOS.tar.zst
(Stored with Git LFS)
Binary file not shown.
@@ -1617,6 +1617,9 @@ module Make<
|
||||
|
||||
/** A static single assignment (SSA) definition. */
|
||||
class SsaDefinition extends FinalDefinition {
|
||||
/** Gets a textual representation of this SSA definition. */
|
||||
string toString() { result = super.toString() }
|
||||
|
||||
/**
|
||||
* Gets the control flow node of this SSA definition.
|
||||
*
|
||||
@@ -1708,6 +1711,8 @@ module Make<
|
||||
class SsaParameterInit extends SsaExplicitWrite {
|
||||
SsaParameterInit() { parameterInit(this, _) }
|
||||
|
||||
override string toString() { result = "SSA param(" + this.getSourceVariable() + ")" }
|
||||
|
||||
/**
|
||||
* Gets the parameter that this definition represents. This is equivalent
|
||||
* to `getDefinition().isParameterInit(result)`
|
||||
@@ -1725,6 +1730,8 @@ module Make<
|
||||
*/
|
||||
class SsaImplicitWrite extends SsaWriteDefinition {
|
||||
SsaImplicitWrite() { not explicitWrite(this, _) }
|
||||
|
||||
override string toString() { result = "SSA implicit def(" + this.getSourceVariable() + ")" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1734,6 +1741,8 @@ module Make<
|
||||
*/
|
||||
class SsaImplicitEntryDefinition extends SsaImplicitWrite {
|
||||
SsaImplicitEntryDefinition() { this.definesAt(_, any(EntryBasicBlock bb), -1) }
|
||||
|
||||
override string toString() { result = "SSA entry def(" + this.getSourceVariable() + ")" }
|
||||
}
|
||||
|
||||
/** An SSA definition that represents an uncertain variable update. */
|
||||
@@ -1761,7 +1770,7 @@ module Make<
|
||||
* ```
|
||||
* a phi definition for `x` is inserted just before the call `puts x`.
|
||||
*/
|
||||
class SsaPhiDefinition extends SsaDefinition {
|
||||
class SsaPhiDefinition extends SsaDefinition instanceof PhiNode {
|
||||
/** Holds if `inp` is an input to this phi definition along the edge originating in `bb`. */
|
||||
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb) {
|
||||
phiHasInputFromBlockCached(this, inp, bb)
|
||||
|
||||
Reference in New Issue
Block a user