@@ -52,6 +52,16 @@ private predicate fieldStep(Node node1, Node node2) {
5252 )
5353}
5454
55+ private predicate closureFlowStep ( Expr e1 , Expr e2 ) {
56+ simpleAstFlowStep ( e1 , e2 )
57+ or
58+ exists ( SsaVariable v |
59+ v .getAUse ( ) = e2 and
60+ v .getAnUltimateDefinition ( ) .( SsaExplicitUpdate ) .getDefiningExpr ( ) .( VariableAssign ) .getSource ( ) =
61+ e1
62+ )
63+ }
64+
5565private module CaptureInput implements VariableCapture:: InputSig {
5666 private import java as J
5767
@@ -60,7 +70,9 @@ private module CaptureInput implements VariableCapture::InputSig {
6070 class BasicBlock instanceof J:: BasicBlock {
6171 string toString ( ) { result = super .toString ( ) }
6272
63- DataFlowCallable getEnclosingCallable ( ) { result .asCallable ( ) = super .getEnclosingCallable ( ) }
73+ Callable getEnclosingCallable ( ) { result = super .getEnclosingCallable ( ) }
74+
75+ Location getLocation ( ) { result = super .getLocation ( ) }
6476 }
6577
6678 BasicBlock getImmediateBasicBlockDominator ( BasicBlock bb ) { bbIDominates ( result , bb ) }
@@ -80,39 +92,59 @@ private module CaptureInput implements VariableCapture::InputSig {
8092
8193 string toString ( ) { result = super .toString ( ) }
8294
83- DataFlowCallable getCallable ( ) { result .asCallable ( ) = super .getCallable ( ) }
95+ Callable getCallable ( ) { result = super .getCallable ( ) }
96+
97+ Location getLocation ( ) { result = super .getLocation ( ) }
8498 }
8599
86100 class CapturedParameter extends CapturedVariable instanceof Parameter { }
87101
88- additional predicate capturedVarUpdate (
89- J:: BasicBlock bb , int i , CapturedVariable v , VariableUpdate upd
90- ) {
91- upd .getDestVar ( ) = v and bb .getNode ( i ) = upd
92- }
102+ class Expr instanceof J:: Expr {
103+ string toString ( ) { result = super .toString ( ) }
104+
105+ Location getLocation ( ) { result = super .getLocation ( ) }
93106
94- additional predicate capturedVarRead ( J:: BasicBlock bb , int i , CapturedVariable v , RValue rv ) {
95- v .( LocalScopeVariable ) .getAnAccess ( ) = rv and bb .getNode ( i ) = rv
107+ predicate hasCfgNode ( BasicBlock bb , int i ) { this = bb .( J:: BasicBlock ) .getNode ( i ) }
96108 }
97109
98- predicate variableWrite ( BasicBlock bb , int i , CapturedVariable v , Location loc ) {
99- exists ( VariableUpdate upd | capturedVarUpdate ( bb , i , v , upd ) and loc = upd .getLocation ( ) )
110+ class VariableWrite extends Expr instanceof VariableUpdate {
111+ CapturedVariable v ;
112+
113+ VariableWrite ( ) { super .getDestVar ( ) = v }
114+
115+ CapturedVariable getVariable ( ) { result = v }
116+
117+ Expr getSource ( ) {
118+ result = this .( VariableAssign ) .getSource ( ) or
119+ result = this .( AssignOp )
120+ }
100121 }
101122
102- predicate variableRead ( BasicBlock bb , int i , CapturedVariable v , Location loc ) {
103- exists ( RValue rv | capturedVarRead ( bb , i , v , rv ) and loc = rv .getLocation ( ) )
123+ class VariableRead extends Expr instanceof RValue {
124+ CapturedVariable v ;
125+
126+ VariableRead ( ) { super .getVariable ( ) = v }
127+
128+ CapturedVariable getVariable ( ) { result = v }
104129 }
105130
106- class Callable = DataFlowCallable ;
131+ class ClosureExpr extends Expr instanceof ClassInstanceExpr {
132+ NestedClass nc ;
107133
108- class Call instanceof DataFlowCall {
109- string toString ( ) { result = super .toString ( ) }
134+ ClosureExpr ( ) {
135+ nc .( AnonymousClass ) .getClassInstanceExpr ( ) = this
136+ or
137+ nc instanceof LocalClass and
138+ super .getConstructedType ( ) .getASourceSupertype * ( ) .getSourceDeclaration ( ) = nc
139+ }
110140
111- Location getLocation ( ) { result = super . getLocation ( ) }
141+ predicate hasBody ( Callable body ) { nc . getACallable ( ) = body }
112142
113- DataFlowCallable getEnclosingCallable ( ) { result = super .getEnclosingCallable ( ) }
143+ predicate hasAliasedAccess ( Expr f ) { closureFlowStep + ( this , f ) and not closureFlowStep ( f , _) }
144+ }
114145
115- predicate hasCfgNode ( BasicBlock bb , int i ) { super .asCall ( ) = bb .( J:: BasicBlock ) .getNode ( i ) }
146+ class Callable extends J:: Callable {
147+ predicate isConstructor ( ) { this instanceof Constructor }
116148 }
117149}
118150
@@ -122,40 +154,27 @@ class CapturedParameter = CaptureInput::CapturedParameter;
122154
123155module CaptureFlow = VariableCapture:: Flow< CaptureInput > ;
124156
157+ CaptureFlow:: ClosureNode asClosureNode ( Node n ) {
158+ result = n .( CaptureNode ) .getSynthesizedCaptureNode ( ) or
159+ result .( CaptureFlow:: ExprNode ) .getExpr ( ) = n .asExpr ( ) or
160+ result .( CaptureFlow:: ExprPostUpdateNode ) .getExpr ( ) =
161+ n .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) or
162+ result .( CaptureFlow:: ParameterNode ) .getParameter ( ) = n .asParameter ( ) or
163+ result .( CaptureFlow:: ThisParameterNode ) .getCallable ( ) = n .( InstanceParameterNode ) .getCallable ( ) or
164+ exprNode ( result .( CaptureFlow:: MallocNode ) .getClosureExpr ( ) ) .( PostUpdateNode ) .getPreUpdateNode ( ) =
165+ n
166+ }
167+
125168private predicate captureStoreStep ( Node node1 , ClosureContent c , Node node2 ) {
126- exists ( BasicBlock bb , int i , CaptureInput:: CapturedVariable v , VariableUpdate upd |
127- upd .( VariableAssign ) .getSource ( ) = node1 .asExpr ( ) or
128- upd .( AssignOp ) = node1 .asExpr ( )
129- |
130- CaptureInput:: capturedVarUpdate ( bb , i , v , upd ) and
131- c .getVariable ( ) = v and
132- CaptureFlow:: storeStep ( bb , i , v , node2 .( ClosureNode ) .getCaptureFlowNode ( ) )
133- )
134- or
135- exists ( Parameter p |
136- node1 .asParameter ( ) = p and
137- c .getVariable ( ) = p and
138- CaptureFlow:: parameterStoreStep ( p , node2 .( ClosureNode ) .getCaptureFlowNode ( ) )
139- )
169+ CaptureFlow:: storeStep ( asClosureNode ( node1 ) , c .getVariable ( ) , asClosureNode ( node2 ) )
140170}
141171
142172private predicate captureReadStep ( Node node1 , ClosureContent c , Node node2 ) {
143- exists ( BasicBlock bb , int i , CaptureInput:: CapturedVariable v |
144- CaptureFlow:: readStep ( node1 .( ClosureNode ) .getCaptureFlowNode ( ) , bb , i , v ) and
145- c .getVariable ( ) = v and
146- CaptureInput:: capturedVarRead ( bb , i , v , node2 .asExpr ( ) )
147- )
148- or
149- exists ( Parameter p |
150- CaptureFlow:: parameterReadStep ( node1 .( ClosureNode ) .getCaptureFlowNode ( ) , p ) and
151- c .getVariable ( ) = p and
152- node2 .( PostUpdateNode ) .getPreUpdateNode ( ) .asParameter ( ) = p
153- )
173+ CaptureFlow:: readStep ( asClosureNode ( node1 ) , c .getVariable ( ) , asClosureNode ( node2 ) )
154174}
155175
156176predicate captureValueStep ( Node node1 , Node node2 ) {
157- CaptureFlow:: localFlowStep ( node1 .( ClosureNode ) .getCaptureFlowNode ( ) ,
158- node2 .( ClosureNode ) .getCaptureFlowNode ( ) )
177+ CaptureFlow:: localFlowStep ( asClosureNode ( node1 ) , asClosureNode ( node2 ) )
159178}
160179
161180/**
@@ -493,6 +512,8 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves
493512 */
494513predicate allowParameterReturnInSelf ( ParameterNode p ) {
495514 FlowSummaryImpl:: Private:: summaryAllowParameterReturnInSelf ( p )
515+ or
516+ CaptureFlow:: heuristicAllowInstanceParameterReturnInSelf ( p .( InstanceParameterNode ) .getCallable ( ) )
496517}
497518
498519/** An approximated `Content`. */
0 commit comments