From f0bd0346f08f9fedb2dc7bd64331b5ba6d7883a1 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 7 Nov 2025 11:03:46 +0100 Subject: [PATCH] Java: Replace usages of SsaVariable. --- .../lib/semmle/code/java/dataflow/NullGuards.qll | 16 +++++++++------- .../lib/semmle/code/java/dataflow/Nullness.qll | 12 ++++++------ .../lib/semmle/code/java/dataflow/RangeUtils.qll | 6 +++--- java/ql/lib/semmle/code/java/dataflow/SSA.qll | 2 +- .../code/java/dataflow/internal/SsaImpl.qll | 2 +- .../rangeanalysis/SignAnalysisSpecific.qll | 2 +- java/ql/test/library-tests/ssa/ssaDef.ql | 4 ++-- 7 files changed, 23 insertions(+), 21 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/NullGuards.qll b/java/ql/lib/semmle/code/java/dataflow/NullGuards.qll index 5928960ea24..b165d1516d6 100644 --- a/java/ql/lib/semmle/code/java/dataflow/NullGuards.qll +++ b/java/ql/lib/semmle/code/java/dataflow/NullGuards.qll @@ -108,7 +108,7 @@ Expr clearlyNotNullExpr(Expr reason) { } /** 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.(SsaExplicitWrite).getValue() and src = clearlyNotNullExpr(reason) @@ -136,7 +136,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 +207,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 +219,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 +228,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 +242,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 +265,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, _)) } diff --git a/java/ql/lib/semmle/code/java/dataflow/Nullness.qll b/java/ql/lib/semmle/code/java/dataflow/Nullness.qll index f2b8f336d09..d8b1c19b07f 100644 --- a/java/ql/lib/semmle/code/java/dataflow/Nullness.qll +++ b/java/ql/lib/semmle/code/java/dataflow/Nullness.qll @@ -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,13 +135,13 @@ 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 + 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. @@ -157,7 +157,7 @@ private predicate varMaybeNull(SsaVariable v, ControlFlowNode node, string msg, // A parameter might be null if there is a null argument somewhere. exists(Parameter p, Expr arg | v.(SsaParameterInit).getParameter() = p and - node = v.getCfgNode() and + node = v.getControlFlowNode() and p.getAnArgument() = arg and reason = arg and msg = "because of $@ null argument" and @@ -266,7 +266,7 @@ private module NullnessFlow = ControlFlowReachability::Flow; * 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 diff --git a/java/ql/lib/semmle/code/java/dataflow/RangeUtils.qll b/java/ql/lib/semmle/code/java/dataflow/RangeUtils.qll index 14b4292db38..269c47dc3b7 100644 --- a/java/ql/lib/semmle/code/java/dataflow/RangeUtils.qll +++ b/java/ql/lib/semmle/code/java/dataflow/RangeUtils.qll @@ -33,7 +33,7 @@ predicate eqFlowCond = U::eqFlowCond/5; * `SsaPhiDefinition` in order for the reflexive case of `nonNullSsaFwdStep*(..)` to * have non-`SsaPhiDefinition` results. */ -private predicate nonNullSsaFwdStep(SsaVariable v, SsaVariable phi) { +private predicate nonNullSsaFwdStep(SsaDefinition v, SsaDefinition phi) { exists(SsaExplicitWrite vnull, SsaPhiDefinition phi0 | phi0 = phi | 2 = strictcount(phi0.getAnInput()) and vnull = phi0.getAnInput() and @@ -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.(SsaExplicitWrite).getValue() = src and nonNullDefStep*(result, src) ) or - exists(SsaVariable mid | + exists(SsaDefinition mid | result = getArrayDef(mid) and nonNullSsaFwdStep(mid, v) ) diff --git a/java/ql/lib/semmle/code/java/dataflow/SSA.qll b/java/ql/lib/semmle/code/java/dataflow/SSA.qll index 5d0214b6357..1f7dce589f7 100644 --- a/java/ql/lib/semmle/code/java/dataflow/SSA.qll +++ b/java/ql/lib/semmle/code/java/dataflow/SSA.qll @@ -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 } } /** diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll index 28f7b300d32..1a60b1c7966 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll @@ -510,7 +510,7 @@ private module Cached { /** Holds if `init` is a closure variable that captures the value of `capturedvar`. */ cached - predicate captures(SsaImplicitEntryDefinition init, SsaVariable capturedvar) { + predicate captures(SsaImplicitEntryDefinition init, SsaDefinition capturedvar) { exists(BasicBlock bb, int i | Ssa::ssaDefReachesUncertainRead(_, capturedvar, bb, i) and variableCapture(capturedvar.getSourceVariable(), init.getSourceVariable(), bb, i) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll index 554ad6a9348..4a418160477 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll @@ -17,7 +17,7 @@ module Private { class Guard = G::Guards_v2::Guard; - class SsaVariable = Ssa::SsaVariable; + class SsaVariable = Ssa::SsaDefinition; class SsaPhiNode = Ssa::SsaPhiDefinition; diff --git a/java/ql/test/library-tests/ssa/ssaDef.ql b/java/ql/test/library-tests/ssa/ssaDef.ql index c487c539e78..a0702d58e0b 100644 --- a/java/ql/test/library-tests/ssa/ssaDef.ql +++ b/java/ql/test/library-tests/ssa/ssaDef.ql @@ -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