Merge branch 'main' into java-kotlin-sensitive-logging-substring-barriers

This commit is contained in:
Paul Hodgkinson
2025-11-20 12:24:22 +00:00
committed by GitHub
481 changed files with 23326 additions and 10191 deletions

View File

@@ -1,3 +1,7 @@
## 7.7.4
No user-facing changes.
## 7.7.3
No user-facing changes.

View 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.

View File

@@ -0,0 +1,3 @@
## 7.7.4
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 7.7.3
lastReleaseVersion: 7.7.4

View File

@@ -1,5 +1,5 @@
name: codeql/java-all
version: 7.7.4-dev
version: 7.7.5-dev
groups: java
dbscheme: config/semmlecode.dbscheme
extractor: java

View File

@@ -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. */

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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
)
}

View File

@@ -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, _))
}

View File

@@ -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

View File

@@ -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() }
}

View File

@@ -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)
)
}

View File

@@ -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

View File

@@ -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

View File

@@ -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)
}
}

View File

@@ -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()
)
}

View File

@@ -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())

View File

@@ -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,

View File

@@ -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
)
}

View File

@@ -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;

View File

@@ -8,7 +8,10 @@ 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 {
/** Gets a use of this variable. */
Expr getAUse() { result = super.getARead() }
}
class Expr = J::Expr;

View File

@@ -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;

View File

@@ -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() }

View File

@@ -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 }

View File

@@ -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()

View File

@@ -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 |

View File

@@ -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()
)

View File

@@ -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()
)
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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
)
}

View File

@@ -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
)
}

View File

@@ -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

View File

@@ -1,3 +1,10 @@
## 1.10.0
### Query Metadata Changes
* Reduced the `security-severity` score of the `java/overly-large-range` query from 5.0 to 4.0 to better reflect its impact.
* Reduced the `security-severity` score of the `java/insecure-cookie` query from 5.0 to 4.0 to better reflect its impact.
## 1.9.0
### New Queries

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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
(

View File

@@ -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

View File

@@ -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

View File

@@ -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, _)
}

View File

@@ -1,5 +1,6 @@
---
category: queryMetadata
---
## 1.10.0
### Query Metadata Changes
* Reduced the `security-severity` score of the `java/overly-large-range` query from 5.0 to 4.0 to better reflect its impact.
* Reduced the `security-severity` score of the `java/insecure-cookie` query from 5.0 to 4.0 to better reflect its impact.
* Reduced the `security-severity` score of the `java/insecure-cookie` query from 5.0 to 4.0 to better reflect its impact.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.9.0
lastReleaseVersion: 1.10.0

View File

@@ -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())
)
}

View File

@@ -1,5 +1,5 @@
name: codeql/java-queries
version: 1.9.1-dev
version: 1.10.1-dev
groups:
- java
- queries

View File

@@ -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) {

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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

View File

@@ -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) |

View File

@@ -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

View File

@@ -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 |

View File

@@ -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

View File

@@ -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) |

View File

@@ -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

View File

@@ -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()

View File

@@ -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 |

View File

@@ -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