Skip to content

Commit a6b8e6a

Browse files
committed
Java: Replace BaseSSA class wrappers with shared code.
1 parent a50c865 commit a6b8e6a

File tree

8 files changed

+200
-149
lines changed

8 files changed

+200
-149
lines changed

java/ql/lib/semmle/code/java/controlflow/Guards.qll

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ private predicate isNonFallThroughPredecessor(SwitchCase sc, ControlFlowNode pre
141141

142142
private module GuardsInput implements SharedGuards::InputSig<Location, ControlFlowNode, BasicBlock> {
143143
private import java as J
144-
private import semmle.code.java.dataflow.internal.BaseSSA
144+
private import semmle.code.java.dataflow.internal.BaseSSA as Base
145145
private import semmle.code.java.dataflow.NullGuards as NullGuards
146146

147147
class NormalExitNode = ControlFlow::NormalExitNode;
@@ -211,10 +211,10 @@ private module GuardsInput implements SharedGuards::InputSig<Location, ControlFl
211211
f.getInitializer() = NullGuards::baseNotNullExpr()
212212
)
213213
or
214-
exists(CatchClause cc, LocalVariableDeclExpr decl, BaseSsaUpdate v |
214+
exists(CatchClause cc, LocalVariableDeclExpr decl, Base::SsaExplicitWrite v |
215215
decl = cc.getVariable() and
216216
decl = v.getDefiningExpr() and
217-
this = v.getAUse()
217+
this = v.getARead()
218218
)
219219
}
220220
}
@@ -407,30 +407,8 @@ private module LogicInputCommon {
407407
}
408408

409409
private module LogicInput_v1 implements GuardsImpl::LogicInputSig {
410-
private import semmle.code.java.dataflow.internal.BaseSSA
411-
412-
final private class FinalBaseSsaVariable = BaseSsaVariable;
413-
414-
class SsaDefinition extends FinalBaseSsaVariable {
415-
GuardsInput::Expr getARead() { result = this.getAUse() }
416-
}
417-
418-
class SsaExplicitWrite extends SsaDefinition instanceof BaseSsaUpdate {
419-
GuardsInput::Expr getValue() {
420-
super.getDefiningExpr().(VariableAssign).getSource() = result or
421-
super.getDefiningExpr().(AssignOp) = result
422-
}
423-
}
424-
425-
class SsaPhiDefinition extends SsaDefinition instanceof BaseSsaPhiNode {
426-
predicate hasInputFromBlock(SsaDefinition inp, BasicBlock bb) {
427-
super.hasInputFromBlock(inp, bb)
428-
}
429-
}
430-
431-
class SsaParameterInit extends SsaDefinition instanceof BaseSsaImplicitInit {
432-
Parameter getParameter() { super.isParameterDefinition(result) }
433-
}
410+
private import semmle.code.java.dataflow.internal.BaseSSA as Base
411+
import Base::Ssa
434412

435413
predicate additionalNullCheck = LogicInputCommon::additionalNullCheck/4;
436414

java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ module;
1212

1313
import java as J
1414
private import semmle.code.java.dispatch.VirtualDispatch
15-
private import semmle.code.java.dataflow.internal.BaseSSA
15+
private import semmle.code.java.dataflow.internal.BaseSSA as Base
1616
private import semmle.code.java.controlflow.Guards
1717
private import codeql.typeflow.TypeFlow
1818
private import codeql.typeflow.UniversalFlow as UniversalFlow
@@ -27,7 +27,7 @@ private RefType boxIfNeeded(J::Type t) {
2727
module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
2828
private newtype TFlowNode =
2929
TField(Field f) { not f.getType() instanceof PrimitiveType } or
30-
TSsa(BaseSsaVariable ssa) { not ssa.getSourceVariable().getType() instanceof PrimitiveType } or
30+
TSsa(Base::SsaDefinition ssa) { not ssa.getSourceVariable().getType() instanceof PrimitiveType } or
3131
TExpr(Expr e) or
3232
TMethod(Method m) { not m.getReturnType() instanceof PrimitiveType }
3333

@@ -55,7 +55,7 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
5555
Field asField() { this = TField(result) }
5656

5757
/** Gets the SSA variable corresponding to this node, if any. */
58-
BaseSsaVariable asSsa() { this = TSsa(result) }
58+
Base::SsaDefinition asSsa() { this = TSsa(result) }
5959

6060
/** Gets the expression corresponding to this node, if any. */
6161
Expr asExpr() { this = TExpr(result) }
@@ -107,7 +107,7 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
107107
not e.(FieldAccess).getField() = f
108108
)
109109
or
110-
n2.asSsa().(BaseSsaPhiNode).getAnUltimateLocalDefinition() = n1.asSsa()
110+
n2.asSsa().(Base::SsaPhiDefinition).getAnUltimateDefinition() = n1.asSsa()
111111
or
112112
exists(ReturnStmt ret |
113113
n2.asMethod() = ret.getEnclosingCallable() and ret.getResult() = n1.asExpr()
@@ -118,24 +118,24 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
118118
exists(Argument arg, Parameter p |
119119
privateParamArg(p, arg) and
120120
n1.asExpr() = arg and
121-
n2.asSsa().(BaseSsaImplicitInit).isParameterDefinition(p) and
121+
n2.asSsa().(Base::SsaParameterInit).getParameter() = p and
122122
// skip trivial recursion
123-
not arg = n2.asSsa().getAUse()
123+
not arg = n2.asSsa().getARead()
124124
)
125125
or
126126
n2.asExpr() = n1.asField().getAnAccess()
127127
or
128-
n2.asExpr() = n1.asSsa().getAUse()
128+
n2.asExpr() = n1.asSsa().getARead()
129129
or
130130
n2.asExpr().(CastingExpr).getExpr() = n1.asExpr() and
131131
not n2.asExpr().getType() instanceof PrimitiveType
132132
or
133133
n2.asExpr().(AssignExpr).getSource() = n1.asExpr() and
134134
not n2.asExpr().getType() instanceof PrimitiveType
135135
or
136-
n2.asSsa().(BaseSsaUpdate).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr()
136+
n2.asSsa().(Base::SsaExplicitWrite).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr()
137137
or
138-
n2.asSsa().(BaseSsaImplicitInit).captures(n1.asSsa())
138+
n2.asSsa().(Base::SsaCapturedDefinition).captures(n1.asSsa())
139139
or
140140
n2.asExpr().(NotNullExpr).getExpr() = n1.asExpr()
141141
}
@@ -147,7 +147,7 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
147147
n.asExpr() instanceof NullLiteral
148148
or
149149
exists(LocalVariableDeclExpr decl |
150-
n.asSsa().(BaseSsaUpdate).getDefiningExpr() = decl and
150+
n.asSsa().(Base::SsaExplicitWrite).getDefiningExpr() = decl and
151151
not decl.hasImplicitInit() and
152152
not exists(decl.getInitOrPatternSource())
153153
)
@@ -216,7 +216,9 @@ private module Input implements TypeFlowInput<Location> {
216216
)
217217
}
218218

219-
private predicate upcastEnhancedForStmtAux(BaseSsaUpdate v, RefType t, RefType t1, RefType t2) {
219+
private predicate upcastEnhancedForStmtAux(
220+
Base::SsaExplicitWrite v, RefType t, RefType t1, RefType t2
221+
) {
220222
exists(EnhancedForStmt for |
221223
for.getVariable() = v.getDefiningExpr() and
222224
v.getSourceVariable().getType().getErasure() = t2 and
@@ -230,17 +232,17 @@ private module Input implements TypeFlowInput<Location> {
230232
* the type of the elements being iterated over, and this type is more precise
231233
* than the type of `v`.
232234
*/
233-
private predicate upcastEnhancedForStmt(BaseSsaUpdate v, RefType t) {
235+
private predicate upcastEnhancedForStmt(Base::SsaExplicitWrite v, RefType t) {
234236
exists(RefType t1, RefType t2 |
235237
upcastEnhancedForStmtAux(v, t, t1, t2) and
236238
t1.getASourceSupertype+() = t2
237239
)
238240
}
239241

240242
private predicate downcastSuccessorAux(
241-
CastingExpr cast, BaseSsaVariable v, RefType t, RefType t1, RefType t2
243+
CastingExpr cast, Base::SsaDefinition v, RefType t, RefType t1, RefType t2
242244
) {
243-
cast.getExpr() = v.getAUse() and
245+
cast.getExpr() = v.getARead() and
244246
t = cast.getType() and
245247
t1 = t.getErasure() and
246248
t2 = v.getSourceVariable().getType().getErasure()
@@ -250,10 +252,10 @@ private module Input implements TypeFlowInput<Location> {
250252
* Holds if `va` is an access to a value that has previously been downcast to `t`.
251253
*/
252254
private predicate downcastSuccessor(VarAccess va, RefType t) {
253-
exists(CastingExpr cast, BaseSsaVariable v, RefType t1, RefType t2 |
255+
exists(CastingExpr cast, Base::SsaDefinition v, RefType t1, RefType t2 |
254256
downcastSuccessorAux(pragma[only_bind_into](cast), v, t, t1, t2) and
255257
t1.getASourceSupertype+() = t2 and
256-
va = v.getAUse() and
258+
va = v.getARead() and
257259
dominates(cast.getControlFlowNode(), va.getControlFlowNode()) and
258260
dominates(cast.getControlFlowNode().getANormalSuccessor(), va.getControlFlowNode())
259261
)
@@ -263,9 +265,9 @@ private module Input implements TypeFlowInput<Location> {
263265
* Holds if `va` is an access to a value that is guarded by `instanceof t` or `case e t`.
264266
*/
265267
private predicate typeTestGuarded(VarAccess va, RefType t) {
266-
exists(Guard typeTest, BaseSsaVariable v |
267-
typeTest.appliesTypeTest(v.getAUse(), t, _) and
268-
va = v.getAUse() and
268+
exists(Guard typeTest, Base::SsaDefinition v |
269+
typeTest.appliesTypeTest(v.getARead(), t, _) and
270+
va = v.getARead() and
269271
guardControls_v1(typeTest, va.getBasicBlock(), true)
270272
)
271273
}
@@ -274,12 +276,12 @@ private module Input implements TypeFlowInput<Location> {
274276
* Holds if `aa` is an access to a value that is guarded by `instanceof t` or `case e t`.
275277
*/
276278
private predicate arrayTypeTestGuarded(ArrayAccess aa, RefType t) {
277-
exists(Guard typeTest, BaseSsaVariable v1, BaseSsaVariable v2, ArrayAccess aa1 |
279+
exists(Guard typeTest, Base::SsaDefinition v1, Base::SsaDefinition v2, ArrayAccess aa1 |
278280
typeTest.appliesTypeTest(aa1, t, _) and
279-
aa1.getArray() = v1.getAUse() and
280-
aa1.getIndexExpr() = v2.getAUse() and
281-
aa.getArray() = v1.getAUse() and
282-
aa.getIndexExpr() = v2.getAUse() and
281+
aa1.getArray() = v1.getARead() and
282+
aa1.getIndexExpr() = v2.getARead() and
283+
aa.getArray() = v1.getARead() and
284+
aa.getIndexExpr() = v2.getARead() and
283285
guardControls_v1(typeTest, aa.getBasicBlock(), true)
284286
)
285287
}
@@ -321,14 +323,14 @@ private module Input implements TypeFlowInput<Location> {
321323
* Holds if `ioe` checks `v`, its true-successor is `bb`, and `bb` has multiple
322324
* predecessors.
323325
*/
324-
private predicate instanceofDisjunct(InstanceOfExpr ioe, BasicBlock bb, BaseSsaVariable v) {
325-
ioe.getExpr() = v.getAUse() and
326+
private predicate instanceofDisjunct(InstanceOfExpr ioe, BasicBlock bb, Base::SsaDefinition v) {
327+
ioe.getExpr() = v.getARead() and
326328
strictcount(bb.getAPredecessor()) > 1 and
327329
exists(ConditionBlock cb | cb.getCondition() = ioe and cb.getTestSuccessor(true) = bb)
328330
}
329331

330332
/** Holds if `bb` is disjunctively guarded by multiple `instanceof` tests on `v`. */
331-
private predicate instanceofDisjunction(BasicBlock bb, BaseSsaVariable v) {
333+
private predicate instanceofDisjunction(BasicBlock bb, Base::SsaDefinition v) {
332334
strictcount(InstanceOfExpr ioe | instanceofDisjunct(ioe, bb, v)) =
333335
strictcount(bb.getAPredecessor())
334336
}
@@ -338,10 +340,10 @@ private module Input implements TypeFlowInput<Location> {
338340
* `instanceof t_i` where `t` is one of those `t_i`.
339341
*/
340342
predicate instanceofDisjunctionGuarded(TypeFlowNode n, RefType t) {
341-
exists(BasicBlock bb, InstanceOfExpr ioe, BaseSsaVariable v, VarAccess va |
343+
exists(BasicBlock bb, InstanceOfExpr ioe, Base::SsaDefinition v, VarAccess va |
342344
instanceofDisjunction(bb, v) and
343345
bb.dominates(va.getBasicBlock()) and
344-
va = v.getAUse() and
346+
va = v.getARead() and
345347
instanceofDisjunct(ioe, bb, v) and
346348
t = ioe.getSyntacticCheckedType() and
347349
n.asExpr() = va

0 commit comments

Comments
 (0)