Skip to content

Commit 254d60c

Browse files
committed
Dataflow: Refactor FlowSummaryImpl to synthesize nodes independently from DataFlow::Node.
1 parent 59636c4 commit 254d60c

File tree

7 files changed

+175
-117
lines changed

7 files changed

+175
-117
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,9 @@ class SummarizedCallableBase extends TSummarizedCallableBase {
149149
or
150150
result = this.asSyntheticCallable().getParameterType(pos)
151151
or
152-
exists(SyntheticCallable sc | sc = this.asSyntheticCallable() |
153-
Impl::Private::summaryParameterNodeRange(this, pos) and
152+
exists(SyntheticCallable sc, Impl::Private::SummaryNode p | sc = this.asSyntheticCallable() |
153+
Impl::Private::summaryParameterNode(p, pos) and
154+
this = p.getSummarizedCallable() and
154155
not exists(sc.getParameterType(pos)) and
155156
result instanceof TypeObject
156157
)

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,7 @@ private module Cached {
5454
fa.getField() instanceof InstanceField and ia.isImplicitFieldQualifier(fa)
5555
)
5656
} or
57-
TSummaryInternalNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
58-
FlowSummaryImpl::Private::summaryNodeRange(c, state)
59-
} or
60-
TSummaryParameterNode(SummarizedCallable c, int pos) {
61-
FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos)
62-
} or
57+
TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn) or
6358
TFieldValueNode(Field f)
6459

6560
cached
@@ -378,8 +373,7 @@ module Private {
378373
result.asCallable() = n.(ImplicitInstanceAccess).getInstanceAccess().getEnclosingCallable() or
379374
result.asCallable() = n.(MallocNode).getClassInstanceExpr().getEnclosingCallable() or
380375
result = nodeGetEnclosingCallable(n.(ImplicitPostUpdateNode).getPreUpdateNode()) or
381-
n = TSummaryInternalNode(result.asSummarizedCallable(), _) or
382-
n = TSummaryParameterNode(result.asSummarizedCallable(), _) or
376+
result.asSummarizedCallable() = n.(FlowSummaryNode).getSummarizedCallable() or
383377
result.asFieldScope() = n.(FieldValueNode).getField()
384378
}
385379

@@ -407,7 +401,7 @@ module Private {
407401
or
408402
this = getInstanceArgument(_)
409403
or
410-
this.(SummaryNode).isArgumentOf(_, _)
404+
this.(FlowSummaryNode).isArgumentOf(_, _)
411405
}
412406

413407
/**
@@ -424,7 +418,7 @@ module Private {
424418
or
425419
pos = -1 and this = getInstanceArgument(call.asCall())
426420
or
427-
this.(SummaryNode).isArgumentOf(call, pos)
421+
this.(FlowSummaryNode).isArgumentOf(call, pos)
428422
}
429423

430424
/** Gets the call in which this node is an argument. */
@@ -435,7 +429,7 @@ module Private {
435429
class ReturnNode extends Node {
436430
ReturnNode() {
437431
exists(ReturnStmt ret | this.asExpr() = ret.getResult()) or
438-
this.(SummaryNode).isReturn()
432+
this.(FlowSummaryNode).isReturn()
439433
}
440434

441435
/** Gets the kind of this returned value. */
@@ -447,61 +441,61 @@ module Private {
447441
OutNode() {
448442
this.asExpr() instanceof MethodAccess
449443
or
450-
this.(SummaryNode).isOut(_)
444+
this.(FlowSummaryNode).isOut(_)
451445
}
452446

453447
/** Gets the underlying call. */
454448
DataFlowCall getCall() {
455449
result.asCall() = this.asExpr()
456450
or
457-
this.(SummaryNode).isOut(result)
451+
this.(FlowSummaryNode).isOut(result)
458452
}
459453
}
460454

461455
/**
462456
* A data-flow node used to model flow summaries.
463457
*/
464-
class SummaryNode extends Node, TSummaryInternalNode {
465-
private SummarizedCallable c;
466-
private FlowSummaryImpl::Private::SummaryNodeState state;
458+
class FlowSummaryNode extends Node, TFlowSummaryNode {
459+
FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) }
467460

468-
SummaryNode() { this = TSummaryInternalNode(c, state) }
461+
SummarizedCallable getSummarizedCallable() {
462+
result = this.getSummaryNode().getSummarizedCallable()
463+
}
469464

470-
override Location getLocation() { result = c.getLocation() }
465+
override Location getLocation() { result = this.getSummarizedCallable().getLocation() }
471466

472-
override string toString() { result = "[summary] " + state + " in " + c }
467+
override string toString() { result = this.getSummaryNode().toString() }
473468

474469
/** Holds if this summary node is the `i`th argument of `call`. */
475470
predicate isArgumentOf(DataFlowCall call, int i) {
476-
FlowSummaryImpl::Private::summaryArgumentNode(call, this, i)
471+
FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), i)
477472
}
478473

479474
/** Holds if this summary node is a return node. */
480-
predicate isReturn() { FlowSummaryImpl::Private::summaryReturnNode(this, _) }
475+
predicate isReturn() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), _) }
481476

482477
/** Holds if this summary node is an out node for `call`. */
483-
predicate isOut(DataFlowCall call) { FlowSummaryImpl::Private::summaryOutNode(call, this, _) }
484-
}
485-
486-
SummaryNode getSummaryNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
487-
result = TSummaryInternalNode(c, state)
478+
predicate isOut(DataFlowCall call) {
479+
FlowSummaryImpl::Private::summaryOutNode(call, this.getSummaryNode(), _)
480+
}
488481
}
489482

490-
class SummaryParameterNode extends ParameterNode, TSummaryParameterNode {
491-
private SummarizedCallable sc;
492-
private int pos_;
493-
494-
SummaryParameterNode() { this = TSummaryParameterNode(sc, pos_) }
495-
496-
override Location getLocation() { result = sc.getLocation() }
483+
class SummaryParameterNode extends ParameterNode, FlowSummaryNode {
484+
SummaryParameterNode() {
485+
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _)
486+
}
497487

498-
override string toString() { result = "[summary param] " + pos_ + " in " + sc }
488+
private int getPosition() {
489+
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), result)
490+
}
499491

500492
override predicate isParameterOf(DataFlowCallable c, int pos) {
501-
c.asSummarizedCallable() = sc and pos = pos_
493+
c.asSummarizedCallable() = this.getSummarizedCallable() and pos = this.getPosition()
502494
}
503495

504-
Type getTypeImpl() { result = sc.getParameterType(pos_) }
496+
Type getTypeImpl() {
497+
result = this.getSummarizedCallable().getParameterType(this.getPosition())
498+
}
505499
}
506500
}
507501

@@ -523,10 +517,12 @@ private class MallocNode extends Node, TMallocNode {
523517
ClassInstanceExpr getClassInstanceExpr() { result = cie }
524518
}
525519

526-
private class SummaryPostUpdateNode extends SummaryNode, PostUpdateNode {
527-
private Node pre;
520+
private class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNode {
521+
private FlowSummaryNode pre;
528522

529-
SummaryPostUpdateNode() { FlowSummaryImpl::Private::summaryPostUpdateNode(this, pre) }
523+
SummaryPostUpdateNode() {
524+
FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), pre.getSummaryNode())
525+
}
530526

531527
override Node getPreUpdateNode() { result = pre }
532528
}

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ predicate jumpStep(Node node1, Node node2) {
8585
any(AdditionalValueStep a).step(node1, node2) and
8686
node1.getEnclosingCallable() != node2.getEnclosingCallable()
8787
or
88-
FlowSummaryImpl::Private::Steps::summaryJumpStep(node1, node2)
88+
FlowSummaryImpl::Private::Steps::summaryJumpStep(node1.(FlowSummaryNode).getSummaryNode(),
89+
node2.(FlowSummaryNode).getSummaryNode())
8990
}
9091

9192
/**
@@ -114,7 +115,8 @@ predicate storeStep(Node node1, Content f, Node node2) {
114115
or
115116
f instanceof ArrayContent and arrayStoreStep(node1, node2)
116117
or
117-
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, f, node2)
118+
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(FlowSummaryNode).getSummaryNode(), f,
119+
node2.(FlowSummaryNode).getSummaryNode())
118120
}
119121

120122
/**
@@ -145,7 +147,8 @@ predicate readStep(Node node1, Content f, Node node2) {
145147
or
146148
f instanceof CollectionContent and collectionReadStep(node1, node2)
147149
or
148-
FlowSummaryImpl::Private::Steps::summaryReadStep(node1, f, node2)
150+
FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(FlowSummaryNode).getSummaryNode(), f,
151+
node2.(FlowSummaryNode).getSummaryNode())
149152
}
150153

151154
/**
@@ -160,15 +163,15 @@ predicate clearsContent(Node n, Content c) {
160163
c.(FieldContent).getField() = fa.getField()
161164
)
162165
or
163-
FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c)
166+
FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(FlowSummaryNode).getSummaryNode(), c)
164167
}
165168

166169
/**
167170
* Holds if the value that is being tracked is expected to be stored inside content `c`
168171
* at node `n`.
169172
*/
170173
predicate expectsContent(Node n, ContentSet c) {
171-
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n, c)
174+
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c)
172175
}
173176

174177
/**
@@ -200,7 +203,7 @@ pragma[noinline]
200203
DataFlowType getNodeType(Node n) {
201204
result = getErasedRepr(n.getTypeBound())
202205
or
203-
result = FlowSummaryImpl::Private::summaryNodeType(n)
206+
result = FlowSummaryImpl::Private::summaryNodeType(n.(FlowSummaryNode).getSummaryNode())
204207
}
205208

206209
/** Gets a string representation of a type returned by `getErasedRepr`. */
@@ -268,7 +271,7 @@ class DataFlowExpr = Expr;
268271

269272
private newtype TDataFlowCall =
270273
TCall(Call c) or
271-
TSummaryCall(SummarizedCallable c, Node receiver) {
274+
TSummaryCall(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver) {
272275
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
273276
}
274277

@@ -318,12 +321,12 @@ class SrcCall extends DataFlowCall, TCall {
318321
/** A synthesized call inside a `SummarizedCallable`. */
319322
class SummaryCall extends DataFlowCall, TSummaryCall {
320323
private SummarizedCallable c;
321-
private Node receiver;
324+
private FlowSummaryImpl::Private::SummaryNode receiver;
322325

323326
SummaryCall() { this = TSummaryCall(c, receiver) }
324327

325328
/** Gets the data flow node that this call targets. */
326-
Node getReceiver() { result = receiver }
329+
FlowSummaryImpl::Private::SummaryNode getReceiver() { result = receiver }
327330

328331
override DataFlowCallable getEnclosingCallable() { result.asSummarizedCallable() = c }
329332

@@ -383,10 +386,7 @@ predicate forceHighPrecision(Content c) {
383386
}
384387

385388
/** Holds if `n` should be hidden from path explanations. */
386-
predicate nodeIsHidden(Node n) {
387-
n instanceof SummaryNode or
388-
n instanceof SummaryParameterNode
389-
}
389+
predicate nodeIsHidden(Node n) { n instanceof FlowSummaryNode }
390390

391391
class LambdaCallKind = Method; // the "apply" method in the functional interface
392392

@@ -404,7 +404,7 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
404404

405405
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
406406
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
407-
receiver = call.(SummaryCall).getReceiver() and
407+
receiver.(FlowSummaryNode).getSummaryNode() = call.(SummaryCall).getReceiver() and
408408
getNodeDataFlowType(receiver)
409409
.getSourceDeclaration()
410410
.(FunctionalInterface)

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,8 @@ private predicate simpleLocalFlowStep0(Node node1, Node node2) {
183183
node1.(ArgumentNode).argumentOf(any(DataFlowCall c | c.asCall() = ma), argNo)
184184
)
185185
or
186-
FlowSummaryImpl::Private::Steps::summaryLocalStep(node1, node2, true)
186+
FlowSummaryImpl::Private::Steps::summaryLocalStep(node1.(FlowSummaryNode).getSummaryNode(),
187+
node2.(FlowSummaryNode).getSummaryNode(), true)
187188
}
188189

189190
/**

0 commit comments

Comments
 (0)