Skip to content

Commit 8916315

Browse files
committed
Java: Replace BaseSSA class wrappers with shared code.
1 parent 0290a81 commit 8916315

File tree

8 files changed

+202
-149
lines changed

8 files changed

+202
-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: 33 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,9 @@ 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) {
31+
not ssa.getSourceVariable().getType() instanceof PrimitiveType
32+
} or
3133
TExpr(Expr e) or
3234
TMethod(Method m) { not m.getReturnType() instanceof PrimitiveType }
3335

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

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

6062
/** Gets the expression corresponding to this node, if any. */
6163
Expr asExpr() { this = TExpr(result) }
@@ -107,7 +109,7 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
107109
not e.(FieldAccess).getField() = f
108110
)
109111
or
110-
n2.asSsa().(BaseSsaPhiNode).getAnUltimateLocalDefinition() = n1.asSsa()
112+
n2.asSsa().(Base::SsaPhiDefinition).getAnUltimateDefinition() = n1.asSsa()
111113
or
112114
exists(ReturnStmt ret |
113115
n2.asMethod() = ret.getEnclosingCallable() and ret.getResult() = n1.asExpr()
@@ -118,24 +120,24 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
118120
exists(Argument arg, Parameter p |
119121
privateParamArg(p, arg) and
120122
n1.asExpr() = arg and
121-
n2.asSsa().(BaseSsaImplicitInit).isParameterDefinition(p) and
123+
n2.asSsa().(Base::SsaParameterInit).getParameter() = p and
122124
// skip trivial recursion
123-
not arg = n2.asSsa().getAUse()
125+
not arg = n2.asSsa().getARead()
124126
)
125127
or
126128
n2.asExpr() = n1.asField().getAnAccess()
127129
or
128-
n2.asExpr() = n1.asSsa().getAUse()
130+
n2.asExpr() = n1.asSsa().getARead()
129131
or
130132
n2.asExpr().(CastingExpr).getExpr() = n1.asExpr() and
131133
not n2.asExpr().getType() instanceof PrimitiveType
132134
or
133135
n2.asExpr().(AssignExpr).getSource() = n1.asExpr() and
134136
not n2.asExpr().getType() instanceof PrimitiveType
135137
or
136-
n2.asSsa().(BaseSsaUpdate).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr()
138+
n2.asSsa().(Base::SsaExplicitWrite).getDefiningExpr().(VariableAssign).getSource() = n1.asExpr()
137139
or
138-
n2.asSsa().(BaseSsaImplicitInit).captures(n1.asSsa())
140+
n2.asSsa().(Base::SsaCapturedDefinition).captures(n1.asSsa())
139141
or
140142
n2.asExpr().(NotNullExpr).getExpr() = n1.asExpr()
141143
}
@@ -147,7 +149,7 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
147149
n.asExpr() instanceof NullLiteral
148150
or
149151
exists(LocalVariableDeclExpr decl |
150-
n.asSsa().(BaseSsaUpdate).getDefiningExpr() = decl and
152+
n.asSsa().(Base::SsaExplicitWrite).getDefiningExpr() = decl and
151153
not decl.hasImplicitInit() and
152154
not exists(decl.getInitOrPatternSource())
153155
)
@@ -216,7 +218,9 @@ private module Input implements TypeFlowInput<Location> {
216218
)
217219
}
218220

219-
private predicate upcastEnhancedForStmtAux(BaseSsaUpdate v, RefType t, RefType t1, RefType t2) {
221+
private predicate upcastEnhancedForStmtAux(
222+
Base::SsaExplicitWrite v, RefType t, RefType t1, RefType t2
223+
) {
220224
exists(EnhancedForStmt for |
221225
for.getVariable() = v.getDefiningExpr() and
222226
v.getSourceVariable().getType().getErasure() = t2 and
@@ -230,17 +234,17 @@ private module Input implements TypeFlowInput<Location> {
230234
* the type of the elements being iterated over, and this type is more precise
231235
* than the type of `v`.
232236
*/
233-
private predicate upcastEnhancedForStmt(BaseSsaUpdate v, RefType t) {
237+
private predicate upcastEnhancedForStmt(Base::SsaExplicitWrite v, RefType t) {
234238
exists(RefType t1, RefType t2 |
235239
upcastEnhancedForStmtAux(v, t, t1, t2) and
236240
t1.getASourceSupertype+() = t2
237241
)
238242
}
239243

240244
private predicate downcastSuccessorAux(
241-
CastingExpr cast, BaseSsaVariable v, RefType t, RefType t1, RefType t2
245+
CastingExpr cast, Base::SsaDefinition v, RefType t, RefType t1, RefType t2
242246
) {
243-
cast.getExpr() = v.getAUse() and
247+
cast.getExpr() = v.getARead() and
244248
t = cast.getType() and
245249
t1 = t.getErasure() and
246250
t2 = v.getSourceVariable().getType().getErasure()
@@ -250,10 +254,10 @@ private module Input implements TypeFlowInput<Location> {
250254
* Holds if `va` is an access to a value that has previously been downcast to `t`.
251255
*/
252256
private predicate downcastSuccessor(VarAccess va, RefType t) {
253-
exists(CastingExpr cast, BaseSsaVariable v, RefType t1, RefType t2 |
257+
exists(CastingExpr cast, Base::SsaDefinition v, RefType t1, RefType t2 |
254258
downcastSuccessorAux(pragma[only_bind_into](cast), v, t, t1, t2) and
255259
t1.getASourceSupertype+() = t2 and
256-
va = v.getAUse() and
260+
va = v.getARead() and
257261
dominates(cast.getControlFlowNode(), va.getControlFlowNode()) and
258262
dominates(cast.getControlFlowNode().getANormalSuccessor(), va.getControlFlowNode())
259263
)
@@ -263,9 +267,9 @@ private module Input implements TypeFlowInput<Location> {
263267
* Holds if `va` is an access to a value that is guarded by `instanceof t` or `case e t`.
264268
*/
265269
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
270+
exists(Guard typeTest, Base::SsaDefinition v |
271+
typeTest.appliesTypeTest(v.getARead(), t, _) and
272+
va = v.getARead() and
269273
guardControls_v1(typeTest, va.getBasicBlock(), true)
270274
)
271275
}
@@ -274,12 +278,12 @@ private module Input implements TypeFlowInput<Location> {
274278
* Holds if `aa` is an access to a value that is guarded by `instanceof t` or `case e t`.
275279
*/
276280
private predicate arrayTypeTestGuarded(ArrayAccess aa, RefType t) {
277-
exists(Guard typeTest, BaseSsaVariable v1, BaseSsaVariable v2, ArrayAccess aa1 |
281+
exists(Guard typeTest, Base::SsaDefinition v1, Base::SsaDefinition v2, ArrayAccess aa1 |
278282
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
283+
aa1.getArray() = v1.getARead() and
284+
aa1.getIndexExpr() = v2.getARead() and
285+
aa.getArray() = v1.getARead() and
286+
aa.getIndexExpr() = v2.getARead() and
283287
guardControls_v1(typeTest, aa.getBasicBlock(), true)
284288
)
285289
}
@@ -321,14 +325,14 @@ private module Input implements TypeFlowInput<Location> {
321325
* Holds if `ioe` checks `v`, its true-successor is `bb`, and `bb` has multiple
322326
* predecessors.
323327
*/
324-
private predicate instanceofDisjunct(InstanceOfExpr ioe, BasicBlock bb, BaseSsaVariable v) {
325-
ioe.getExpr() = v.getAUse() and
328+
private predicate instanceofDisjunct(InstanceOfExpr ioe, BasicBlock bb, Base::SsaDefinition v) {
329+
ioe.getExpr() = v.getARead() and
326330
strictcount(bb.getAPredecessor()) > 1 and
327331
exists(ConditionBlock cb | cb.getCondition() = ioe and cb.getTestSuccessor(true) = bb)
328332
}
329333

330334
/** Holds if `bb` is disjunctively guarded by multiple `instanceof` tests on `v`. */
331-
private predicate instanceofDisjunction(BasicBlock bb, BaseSsaVariable v) {
335+
private predicate instanceofDisjunction(BasicBlock bb, Base::SsaDefinition v) {
332336
strictcount(InstanceOfExpr ioe | instanceofDisjunct(ioe, bb, v)) =
333337
strictcount(bb.getAPredecessor())
334338
}
@@ -338,10 +342,10 @@ private module Input implements TypeFlowInput<Location> {
338342
* `instanceof t_i` where `t` is one of those `t_i`.
339343
*/
340344
predicate instanceofDisjunctionGuarded(TypeFlowNode n, RefType t) {
341-
exists(BasicBlock bb, InstanceOfExpr ioe, BaseSsaVariable v, VarAccess va |
345+
exists(BasicBlock bb, InstanceOfExpr ioe, Base::SsaDefinition v, VarAccess va |
342346
instanceofDisjunction(bb, v) and
343347
bb.dominates(va.getBasicBlock()) and
344-
va = v.getAUse() and
348+
va = v.getARead() and
345349
instanceofDisjunct(ioe, bb, v) and
346350
t = ioe.getSyntacticCheckedType() and
347351
n.asExpr() = va

0 commit comments

Comments
 (0)