Skip to content

Commit 90052a3

Browse files
committed
Java: Add proper types for capture nodes.
1 parent e2a0849 commit 90052a3

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -503,14 +503,21 @@ module Private {
503503
* captured variables.
504504
*/
505505
class CaptureNode extends Node, TCaptureNode {
506-
CaptureFlow::SynthesizedCaptureNode getSynthesizedCaptureNode() { this = TCaptureNode(result) }
506+
private CaptureFlow::SynthesizedCaptureNode cn;
507507

508-
override Location getLocation() { result = this.getSynthesizedCaptureNode().getLocation() }
508+
CaptureNode() { this = TCaptureNode(cn) }
509509

510-
override string toString() { result = this.getSynthesizedCaptureNode().toString() }
510+
CaptureFlow::SynthesizedCaptureNode getSynthesizedCaptureNode() { result = cn }
511511

512-
// TODO: expose hasTypeProxy(var / callable)
513-
Type getTypeImpl() { result instanceof TypeObject }
512+
override Location getLocation() { result = cn.getLocation() }
513+
514+
override string toString() { result = cn.toString() }
515+
516+
Type getTypeImpl() {
517+
exists(Variable v | cn.isVariableAccess(v) and result = v.getType())
518+
or
519+
cn.isInstanceAccess() and result = cn.getEnclosingCallable().getDeclaringType()
520+
}
514521
}
515522
}
516523

shared/dataflow/codeql/dataflow/VariableCapture.qll

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ signature module OutputSig<InputSig I> {
167167

168168
/** Gets the enclosing callable. */
169169
I::Callable getEnclosingCallable();
170+
171+
/** Holds if this node is a synthesized access of `v`. */
172+
predicate isVariableAccess(I::CapturedVariable v);
173+
174+
/** Holds if this node is a synthesized instance access. */
175+
predicate isInstanceAccess();
170176
}
171177

172178
/** A data flow node for an expression. */
@@ -740,6 +746,22 @@ module Flow<InputSig Input> implements OutputSig<Input> {
740746
this = TSynthPhi(phi) and phi.definesAt(_, bb, _, _) and result = bb.getEnclosingCallable()
741747
)
742748
}
749+
750+
predicate isVariableAccess(CapturedVariable v) {
751+
this = TSynthRead(v, _, _, _)
752+
or
753+
exists(CaptureSsa::DefinitionExt phi |
754+
this = TSynthPhi(phi) and phi.definesAt(TVariable(v), _, _, _)
755+
)
756+
}
757+
758+
predicate isInstanceAccess() {
759+
this instanceof TSynthThisQualifier
760+
or
761+
exists(CaptureSsa::DefinitionExt phi |
762+
this = TSynthPhi(phi) and phi.definesAt(TThis(_), _, _, _)
763+
)
764+
}
743765
}
744766

745767
class ExprNode extends ClosureNode, TExprNode {

0 commit comments

Comments
 (0)