Java: Replace uses of SsaExplicitUpdate.

This commit is contained in:
Anders Schack-Mulligen
2025-11-07 09:16:41 +01:00
parent 07e635636c
commit 483b2d89a7
17 changed files with 57 additions and 54 deletions

View File

@@ -35,7 +35,7 @@ predicate useUsePair(VarRead use1, VarRead use2) { adjacentUseUse+(use1, use2) }
*/
predicate defUsePair(VariableUpdate def, VarRead use) {
exists(SsaVariable v |
v.getAUse() = use and v.getAnUltimateDefinition().(SsaExplicitUpdate).getDefiningExpr() = def
v.getAUse() = use and v.getAnUltimateDefinition().(SsaExplicitWrite).getDefiningExpr() = def
)
}

View File

@@ -110,13 +110,13 @@ Expr clearlyNotNullExpr(Expr reason) {
/** Holds if `v` is an SSA variable that is provably not `null`. */
predicate clearlyNotNull(SsaVariable 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

View File

@@ -151,7 +151,7 @@ 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.
@@ -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"
@@ -185,7 +185,7 @@ private Expr nonEmptyExpr() {
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 |
@@ -280,7 +280,7 @@ predicate nullDeref(SsaSourceVariable v, VarAccess va, string msg, Expr reason)
predicate alwaysNullDeref(SsaSourceVariable v, VarAccess va) {
exists(BasicBlock bb, SsaVariable ssa |
forall(SsaVariable def | def = ssa.getAnUltimateDefinition() |
def.(SsaExplicitUpdate).getDefiningExpr().(VariableAssign).getSource() = alwaysNullExpr()
def.(SsaExplicitWrite).getValue() = alwaysNullExpr()
)
or
nullGuardControls(ssa, true, bb) and

View File

@@ -252,7 +252,7 @@ module Sem implements Semantic<Location> {
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

@@ -34,13 +34,13 @@ predicate eqFlowCond = U::eqFlowCond/5;
* have non-`SsaPhiNode` results.
*/
private predicate nonNullSsaFwdStep(SsaVariable v, SsaVariable phi) {
exists(SsaExplicitUpdate vnull, SsaPhiNode phi0 | phi0 = phi |
exists(SsaExplicitWrite vnull, SsaPhiNode phi0 | phi0 = phi |
2 = strictcount(phi0.getAPhiInput()) and
vnull = phi0.getAPhiInput() and
v = phi0.getAPhiInput() and
not backEdge(phi0, v, _) and
vnull != v and
vnull.getDefiningExpr().(VariableAssign).getSource() instanceof NullLiteral
vnull.getValue() instanceof NullLiteral
)
}
@@ -58,7 +58,7 @@ private predicate nonNullDefStep(Expr e1, Expr e2) {
*/
ArrayCreationExpr getArrayDef(SsaVariable v) {
exists(Expr src |
v.(SsaExplicitUpdate).getDefiningExpr().(VariableAssign).getSource() = src and
v.(SsaExplicitWrite).getValue() = src and
nonNullDefStep*(result, src)
)
or
@@ -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

@@ -215,7 +215,11 @@ 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;
@@ -368,7 +372,7 @@ private class RefTypeCastingExpr extends CastingExpr {
Expr sameValue(SsaVariable v, VarAccess va) {
result = v.getAUse() 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

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

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

View File

@@ -64,8 +64,7 @@ private predicate closureFlowStep(Expr e1, Expr e2) {
or
exists(SsaVariable v |
v.getAUse() = e2 and
v.getAnUltimateDefinition().(SsaExplicitUpdate).getDefiningExpr().(VariableAssign).getSource() =
e1
v.getAnUltimateDefinition().(SsaExplicitWrite).getValue() = e1
)
}
@@ -395,7 +394,7 @@ 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(),
@@ -531,9 +530,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)
)
}

View File

@@ -668,9 +668,7 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
Expr getARead(Definition def) { result = getAUse(def) }
predicate ssaDefHasSource(WriteDefinition def) {
def instanceof SsaExplicitUpdate or def instanceof SsaParameterInit
}
predicate ssaDefHasSource(WriteDefinition def) { def instanceof SsaExplicitWrite }
predicate allowFlowIntoUncertainDef(UncertainWriteDefinition def) {
def instanceof SsaUncertainImplicitUpdate

View File

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

View File

@@ -55,7 +55,7 @@ private class InputStreamWrapperCapturedLocalStep extends AdditionalTaintStep {
.getASourceSupertype*()
.getSourceDeclaration() = wrapper
|
n1.asExpr() = captured.(SsaExplicitUpdate).getDefiningExpr().(VariableAssign).getSource()
n1.asExpr() = captured.(SsaExplicitWrite).getDefiningExpr().(VariableAssign).getSource()
or
captured.(SsaParameterInit).getParameter() = n1.asParameter()
)

View File

@@ -40,7 +40,7 @@ private predicate isShell(Expr ex) {
or
exists(SsaVariable ssa |
ex = ssa.getAUse() and
isShell(ssa.getAnUltimateDefinition().(SsaExplicitUpdate).getDefiningExpr())
isShell(ssa.getAnUltimateDefinition().(SsaExplicitWrite).getDefiningExpr())
)
or
isShell(ex.(Assignment).getRhs())
@@ -61,10 +61,10 @@ 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%")
)
}
@@ -87,7 +87,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 +121,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 +133,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()
@@ -173,7 +173,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

@@ -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
@@ -161,8 +161,8 @@ Expr increaseOrDecreaseOfVar(SsaVariable v) {
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)

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

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