Skip to content

Commit 6e495ba

Browse files
authored
Merge pull request #10068 from aschackmull/java/summarizedcallable-split
Java: Make synthesized method bodies disjoint from source code.
2 parents 355c1f5 + c034a1e commit 6e495ba

File tree

10 files changed

+77
-73
lines changed

10 files changed

+77
-73
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ private module DispatchImpl {
1010
DataFlowCallable viableCallable(DataFlowCall c) {
1111
result.asCallable() = VirtualDispatch::viableCallable(c.asCall())
1212
or
13-
result.asCallable().(SummarizedCallable) = c.asCall().getCallee().getSourceDeclaration()
13+
result.asSummarizedCallable() = c.asCall().getCallee().getSourceDeclaration()
1414
}
1515

1616
/**
@@ -118,7 +118,7 @@ private module DispatchImpl {
118118
not failsUnification(t, t2)
119119
)
120120
or
121-
result.asCallable() = def and def instanceof SummarizedCallable
121+
result.asSummarizedCallable() = def
122122
)
123123
}
124124

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

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,12 @@ newtype TNode =
1313
not e.getType() instanceof VoidType and
1414
not e.getParent*() instanceof Annotation
1515
} or
16-
TExplicitParameterNode(Parameter p) {
17-
exists(p.getCallable().getBody()) or p.getCallable() instanceof SummarizedCallable
18-
} or
16+
TExplicitParameterNode(Parameter p) { exists(p.getCallable().getBody()) } or
1917
TImplicitVarargsArray(Call c) {
2018
c.getCallee().isVarargs() and
2119
not exists(Argument arg | arg.getCall() = c and arg.isExplicitVarargsArray())
2220
} or
23-
TInstanceParameterNode(Callable c) {
24-
(exists(c.getBody()) or c instanceof SummarizedCallable) and
25-
not c.isStatic()
26-
} or
21+
TInstanceParameterNode(Callable c) { exists(c.getBody()) and not c.isStatic() } or
2722
TImplicitInstanceAccess(InstanceAccessExt ia) { not ia.isExplicit(_) } or
2823
TMallocNode(ClassInstanceExpr cie) or
2924
TExplicitExprPostUpdate(Expr e) {
@@ -45,6 +40,9 @@ newtype TNode =
4540
TSummaryInternalNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
4641
FlowSummaryImpl::Private::summaryNodeRange(c, state)
4742
} or
43+
TSummaryParameterNode(SummarizedCallable c, int pos) {
44+
FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos)
45+
} or
4846
TFieldValueNode(Field f)
4947

5048
private predicate explicitInstanceArgument(Call call, Expr instarg) {
@@ -96,6 +94,8 @@ module Public {
9694
or
9795
result = this.(ImplicitPostUpdateNode).getPreUpdateNode().getType()
9896
or
97+
result = this.(SummaryParameterNode).getTypeImpl()
98+
or
9999
result = this.(FieldValueNode).getField().getType()
100100
}
101101

@@ -155,7 +155,7 @@ module Public {
155155
* Holds if this node is the parameter of `c` at the specified (zero-based)
156156
* position. The implicit `this` parameter is considered to have index `-1`.
157157
*/
158-
abstract predicate isParameterOf(Callable c, int pos);
158+
abstract predicate isParameterOf(DataFlowCallable c, int pos);
159159
}
160160

161161
/**
@@ -173,7 +173,9 @@ module Public {
173173
/** Gets the parameter corresponding to this node. */
174174
Parameter getParameter() { result = param }
175175

176-
override predicate isParameterOf(Callable c, int pos) { c.getParameter(pos) = param }
176+
override predicate isParameterOf(DataFlowCallable c, int pos) {
177+
c.asCallable().getParameter(pos) = param
178+
}
177179
}
178180

179181
/** Gets the node corresponding to `p`. */
@@ -213,7 +215,9 @@ module Public {
213215
/** Gets the callable containing this `this` parameter. */
214216
Callable getCallable() { result = callable }
215217

216-
override predicate isParameterOf(Callable c, int pos) { callable = c and pos = -1 }
218+
override predicate isParameterOf(DataFlowCallable c, int pos) {
219+
callable = c.asCallable() and pos = -1
220+
}
217221
}
218222

219223
/**
@@ -336,13 +340,14 @@ module Private {
336340
result.asCallable() = n.(ImplicitInstanceAccess).getInstanceAccess().getEnclosingCallable() or
337341
result.asCallable() = n.(MallocNode).getClassInstanceExpr().getEnclosingCallable() or
338342
result = nodeGetEnclosingCallable(n.(ImplicitPostUpdateNode).getPreUpdateNode()) or
339-
n = TSummaryInternalNode(result.asCallable(), _) or
343+
n = TSummaryInternalNode(result.asSummarizedCallable(), _) or
344+
n = TSummaryParameterNode(result.asSummarizedCallable(), _) or
340345
result.asFieldScope() = n.(FieldValueNode).getField()
341346
}
342347

343348
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
344349
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) {
345-
p.isParameterOf(c.asCallable(), pos)
350+
p.isParameterOf(c, pos)
346351
}
347352

348353
/** Holds if `arg` is an `ArgumentNode` of `c` with position `pos`. */
@@ -443,6 +448,27 @@ module Private {
443448
SummaryNode getSummaryNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
444449
result = TSummaryInternalNode(c, state)
445450
}
451+
452+
class SummaryParameterNode extends ParameterNode, TSummaryParameterNode {
453+
private SummarizedCallable sc;
454+
private int pos_;
455+
456+
SummaryParameterNode() { this = TSummaryParameterNode(sc, pos_) }
457+
458+
override Location getLocation() { result = sc.getLocation() }
459+
460+
override string toString() { result = "[summary param] " + pos_ + " in " + sc }
461+
462+
override predicate isParameterOf(DataFlowCallable c, int pos) {
463+
c.asSummarizedCallable() = sc and pos = pos_
464+
}
465+
466+
Type getTypeImpl() {
467+
result = sc.getParameter(pos_).getType()
468+
or
469+
pos_ = -1 and result = sc.getDeclaringType()
470+
}
471+
}
446472
}
447473

448474
private import Private

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,26 +230,32 @@ class CastNode extends ExprNode {
230230
}
231231

232232
private newtype TDataFlowCallable =
233-
TCallable(Callable c) or
233+
TSrcCallable(Callable c) or
234+
TSummarizedCallable(SummarizedCallable c) or
234235
TFieldScope(Field f)
235236

236237
class DataFlowCallable extends TDataFlowCallable {
237-
Callable asCallable() { this = TCallable(result) }
238+
Callable asCallable() { this = TSrcCallable(result) }
239+
240+
SummarizedCallable asSummarizedCallable() { this = TSummarizedCallable(result) }
238241

239242
Field asFieldScope() { this = TFieldScope(result) }
240243

241244
RefType getDeclaringType() {
242245
result = this.asCallable().getDeclaringType() or
246+
result = this.asSummarizedCallable().getDeclaringType() or
243247
result = this.asFieldScope().getDeclaringType()
244248
}
245249

246250
string toString() {
247251
result = this.asCallable().toString() or
252+
result = "Synthetic: " + this.asSummarizedCallable().toString() or
248253
result = "Field scope: " + this.asFieldScope().toString()
249254
}
250255

251256
Location getLocation() {
252257
result = this.asCallable().getLocation() or
258+
result = this.asSummarizedCallable().getLocation() or
253259
result = this.asFieldScope().getLocation()
254260
}
255261
}
@@ -317,7 +323,7 @@ class SummaryCall extends DataFlowCall, TSummaryCall {
317323
/** Gets the data flow node that this call targets. */
318324
Node getReceiver() { result = receiver }
319325

320-
override DataFlowCallable getEnclosingCallable() { result.asCallable() = c }
326+
override DataFlowCallable getEnclosingCallable() { result.asSummarizedCallable() = c }
321327

322328
override string toString() { result = "[summary] call to " + receiver + " in " + c }
323329

@@ -376,9 +382,8 @@ predicate forceHighPrecision(Content c) {
376382

377383
/** Holds if `n` should be hidden from path explanations. */
378384
predicate nodeIsHidden(Node n) {
379-
n instanceof SummaryNode
380-
or
381-
n.(ParameterNode).isParameterOf(any(SummarizedCallable c), _)
385+
n instanceof SummaryNode or
386+
n instanceof SummaryParameterNode
382387
}
383388

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ private module FlowSummaries {
1616

1717
class SummarizedCallableBase = Callable;
1818

19-
DataFlowCallable inject(SummarizedCallable c) { result.asCallable() = c }
19+
DataFlowCallable inject(SummarizedCallable c) { result.asSummarizedCallable() = c }
2020

2121
/** Gets the parameter position of the instance parameter. */
2222
int instanceParameterPosition() { result = -1 }

java/ql/lib/semmle/code/java/dispatch/DispatchFlow.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ private class RelevantNode extends Node {
131131
*/
132132
pragma[nomagic]
133133
private predicate viableParamCand(Call call, int i, ParameterNode p) {
134-
exists(Callable callable |
135-
callable = dispatchCand(call) and
134+
exists(DataFlowCallable callable |
135+
callable.asCallable() = dispatchCand(call) and
136136
p.isParameterOf(callable, i) and
137137
p instanceof RelevantNode
138138
)

java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ private Callable dispatchCand(Call c) {
3333
*/
3434
pragma[nomagic]
3535
private predicate viableParam(Call call, int i, ParameterNode p) {
36-
exists(Callable callable |
37-
callable = dispatchCand(call) and
36+
exists(DataFlowCallable callable |
37+
callable.asCallable() = dispatchCand(call) and
3838
p.isParameterOf(callable, i)
3939
)
4040
}

0 commit comments

Comments
 (0)