Skip to content

Commit e7709f7

Browse files
authored
Merge pull request #4099 from hvitved/java/dataflow/unique-encl-callable
Java: Use `unique` aggregate in `Node::getEnclosingCallable()`
2 parents 83884c0 + 1357796 commit e7709f7

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

docs/ql-libraries/dataflow/dataflow.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ Recommendations:
9898
also work, but the upside of `use-use` steps is that sources defined in terms
9999
of variable reads just work out of the box. It also makes certain
100100
barrier-implementations simpler.
101+
* A predicate `DataFlowCallable Node::getEnclosingCallable()` is required, and in
102+
order to ensure appropriate join-orders, it is important that the QL compiler knows
103+
that this predicate is functional. It can therefore be necessary to enclose the body
104+
of this predicate in a `unique` aggregate.
101105

102106
The shared library does not use `localFlowStep` nor `localFlow` but users of
103107
`DataFlow.qll` may expect the existence of `DataFlow::localFlowStep` and

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,19 @@ class Node extends TNode {
7878
result = this.(ImplicitPostUpdateNode).getPreUpdateNode().getType()
7979
}
8080

81-
/** Gets the callable in which this node occurs. */
82-
Callable getEnclosingCallable() {
81+
private Callable getEnclosingCallableImpl() {
8382
result = this.asExpr().getEnclosingCallable() or
8483
result = this.asParameter().getCallable() or
8584
result = this.(ImplicitVarargsArray).getCall().getEnclosingCallable() or
8685
result = this.(InstanceParameterNode).getCallable() or
8786
result = this.(ImplicitInstanceAccess).getInstanceAccess().getEnclosingCallable() or
8887
result = this.(MallocNode).getClassInstanceExpr().getEnclosingCallable() or
89-
result = this.(ImplicitPostUpdateNode).getPreUpdateNode().getEnclosingCallable()
88+
result = this.(ImplicitPostUpdateNode).getPreUpdateNode().getEnclosingCallableImpl()
89+
}
90+
91+
/** Gets the callable in which this node occurs. */
92+
Callable getEnclosingCallable() {
93+
result = unique(DataFlowCallable c | c = this.getEnclosingCallableImpl() | c)
9094
}
9195

9296
private Type getImprovedTypeBound() {

0 commit comments

Comments
 (0)