@@ -699,6 +699,7 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
699699 class SourceVariable = CaptureContainer ;
700700
701701 predicate variableWrite ( BasicBlock bb , int i , SourceVariable cc , boolean certain ) {
702+ Cached:: ref ( ) and
702703 (
703704 exists ( CapturedVariable v | cc = TVariable ( v ) and captureWrite ( v , bb , i , true , _) )
704705 or
@@ -721,23 +722,55 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
721722
722723 private module CaptureSsa = Ssa:: Make< Location , CaptureSsaInput > ;
723724
724- private newtype TClosureNode =
725- TSynthRead ( CapturedVariable v , BasicBlock bb , int i , Boolean isPost ) {
726- synthRead ( v , bb , i , _, _)
727- } or
728- TSynthThisQualifier ( BasicBlock bb , int i , Boolean isPost ) { synthThisQualifier ( bb , i ) } or
729- TSynthPhi ( CaptureSsa:: DefinitionExt phi ) {
730- phi instanceof CaptureSsa:: PhiNode or phi instanceof CaptureSsa:: PhiReadNode
731- } or
732- TExprNode ( Expr expr , Boolean isPost ) {
733- expr instanceof VariableRead
734- or
735- synthRead ( _, _, _, _, expr )
736- } or
737- TParamNode ( CapturedParameter p ) or
738- TThisParamNode ( Callable c ) { captureAccess ( _, c ) } or
739- TMallocNode ( ClosureExpr ce ) { hasConstructorCapture ( ce , _) } or
740- TVariableWriteSourceNode ( VariableWrite write )
725+ private module DataFlowIntegrationInput implements CaptureSsa:: DataFlowIntegrationInputSig {
726+ private import codeql.util.Void
727+
728+ class Expr instanceof Input:: ControlFlowNode {
729+ string toString ( ) { result = super .toString ( ) }
730+
731+ predicate hasCfgNode ( BasicBlock bb , int i ) { bb .getNode ( i ) = this }
732+ }
733+
734+ class Guard extends Void {
735+ predicate controlsBranchEdge ( BasicBlock bb1 , BasicBlock bb2 , boolean branch ) { none ( ) }
736+ }
737+
738+ predicate guardDirectlyControlsBlock ( Guard guard , BasicBlock bb , boolean branch ) { none ( ) }
739+
740+ predicate includeWriteDefsInFlowStep ( ) { none ( ) }
741+
742+ predicate supportBarrierGuardsOnPhiEdges ( ) { none ( ) }
743+ }
744+
745+ private module SsaFlow = CaptureSsa:: DataFlowIntegration< DataFlowIntegrationInput > ;
746+
747+ cached
748+ private module Cached {
749+ cached
750+ predicate ref ( ) { any ( ) }
751+
752+ cached
753+ predicate backref ( ) { localFlowStep ( _, _) implies any ( ) }
754+
755+ cached
756+ newtype TClosureNode =
757+ TSynthRead ( CapturedVariable v , BasicBlock bb , int i , Boolean isPost ) {
758+ synthRead ( v , bb , i , _, _)
759+ } or
760+ TSynthThisQualifier ( BasicBlock bb , int i , Boolean isPost ) { synthThisQualifier ( bb , i ) } or
761+ TSynthSsa ( SsaFlow:: SsaNode n ) or
762+ TExprNode ( Expr expr , Boolean isPost ) {
763+ expr instanceof VariableRead
764+ or
765+ synthRead ( _, _, _, _, expr )
766+ } or
767+ TParamNode ( CapturedParameter p ) or
768+ TThisParamNode ( Callable c ) { captureAccess ( _, c ) } or
769+ TMallocNode ( ClosureExpr ce ) { hasConstructorCapture ( ce , _) } or
770+ TVariableWriteSourceNode ( VariableWrite write )
771+ }
772+
773+ private import Cached
741774
742775 class ClosureNode extends TClosureNode {
743776 /** Gets a textual representation of this node. */
@@ -746,11 +779,7 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
746779 or
747780 result = "this" and this = TSynthThisQualifier ( _, _, _)
748781 or
749- exists ( CaptureSsa:: DefinitionExt phi , CaptureContainer cc |
750- this = TSynthPhi ( phi ) and
751- phi .definesAt ( cc , _, _, _) and
752- result = "phi(" + cc .toString ( ) + ")"
753- )
782+ exists ( SsaFlow:: SsaNode n | this = TSynthSsa ( n ) and result = n .toString ( ) )
754783 or
755784 exists ( Expr expr , boolean isPost | this = TExprNode ( expr , isPost ) |
756785 isPost = false and result = expr .toString ( )
@@ -784,9 +813,7 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
784813 captureWrite ( _, bb , i , false , any ( VariableWrite vw | result = vw .getLocation ( ) ) )
785814 )
786815 or
787- exists ( CaptureSsa:: DefinitionExt phi , BasicBlock bb |
788- this = TSynthPhi ( phi ) and phi .definesAt ( _, bb , _, _) and result = bb .getLocation ( )
789- )
816+ exists ( SsaFlow:: SsaNode n | this = TSynthSsa ( n ) and result = n .getLocation ( ) )
790817 or
791818 exists ( Expr expr | this = TExprNode ( expr , _) and result = expr .getLocation ( ) )
792819 or
@@ -802,35 +829,29 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
802829 }
803830 }
804831
805- private class TSynthesizedCaptureNode = TSynthRead or TSynthThisQualifier or TSynthPhi ;
832+ private class TSynthesizedCaptureNode = TSynthRead or TSynthThisQualifier or TSynthSsa ;
806833
807834 class SynthesizedCaptureNode extends ClosureNode , TSynthesizedCaptureNode {
808835 BasicBlock getBasicBlock ( ) {
809836 this = TSynthRead ( _, result , _, _)
810837 or
811838 this = TSynthThisQualifier ( result , _, _)
812839 or
813- exists ( CaptureSsa:: DefinitionExt phi |
814- this = TSynthPhi ( phi ) and phi .definesAt ( _, result , _, _)
815- )
840+ exists ( SsaFlow:: SsaNode n | this = TSynthSsa ( n ) and n .getBasicBlock ( ) = result )
816841 }
817842
818843 Callable getEnclosingCallable ( ) { result = this .getBasicBlock ( ) .getEnclosingCallable ( ) }
819844
820845 predicate isVariableAccess ( CapturedVariable v ) {
821846 this = TSynthRead ( v , _, _, _)
822847 or
823- exists ( CaptureSsa:: DefinitionExt phi |
824- this = TSynthPhi ( phi ) and phi .definesAt ( TVariable ( v ) , _, _, _)
825- )
848+ exists ( SsaFlow:: SsaNode n | this = TSynthSsa ( n ) and n .getSourceVariable ( ) = TVariable ( v ) )
826849 }
827850
828851 predicate isInstanceAccess ( ) {
829852 this instanceof TSynthThisQualifier
830853 or
831- exists ( CaptureSsa:: DefinitionExt phi |
832- this = TSynthPhi ( phi ) and phi .definesAt ( TThis ( _) , _, _, _)
833- )
854+ exists ( SsaFlow:: SsaNode n | this = TSynthSsa ( n ) and n .getSourceVariable ( ) = TThis ( _) )
834855 }
835856 }
836857
@@ -872,18 +893,7 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
872893 )
873894 }
874895
875- private predicate step ( CaptureContainer cc , BasicBlock bb1 , int i1 , BasicBlock bb2 , int i2 ) {
876- CaptureSsa:: adjacentDefReadExt ( _, cc , bb1 , i1 , bb2 , i2 )
877- }
878-
879- private predicate stepToPhi ( CaptureContainer cc , BasicBlock bb , int i , TSynthPhi phi ) {
880- exists ( CaptureSsa:: DefinitionExt next |
881- CaptureSsa:: lastRefRedefExt ( _, cc , bb , i , next ) and
882- phi = TSynthPhi ( next )
883- )
884- }
885-
886- private predicate ssaAccessAt (
896+ private predicate ssaReadAt (
887897 ClosureNode n , CaptureContainer cc , boolean isPost , BasicBlock bb , int i
888898 ) {
889899 exists ( CapturedVariable v |
@@ -894,49 +904,57 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
894904 or
895905 n = TSynthThisQualifier ( bb , i , isPost ) and cc = TThis ( bb .getEnclosingCallable ( ) )
896906 or
897- exists ( CaptureSsa:: DefinitionExt phi |
898- n = TSynthPhi ( phi ) and phi .definesAt ( cc , bb , i , _) and isPost = false
899- )
900- or
901907 exists ( VariableRead vr , CapturedVariable v |
902908 captureRead ( v , bb , i , true , vr ) and
903909 n = TExprNode ( vr , isPost ) and
904910 cc = TVariable ( v )
905911 )
906- or
912+ }
913+
914+ private predicate ssaWriteAt ( ClosureNode n , CaptureContainer cc , BasicBlock bb , int i ) {
907915 exists ( VariableWrite vw , CapturedVariable v |
908916 captureWrite ( v , bb , i , true , vw ) and
909917 n = TVariableWriteSourceNode ( vw ) and
910- isPost = false and
911918 cc = TVariable ( v )
912919 )
913920 or
914921 exists ( CapturedParameter p |
915922 entryDef ( cc , bb , i ) and
916923 cc = TVariable ( p ) and
917- n = TParamNode ( p ) and
918- isPost = false
924+ n = TParamNode ( p )
919925 )
920926 or
921927 exists ( Callable c |
922928 entryDef ( cc , bb , i ) and
923929 cc = TThis ( c ) and
924- n = TThisParamNode ( c ) and
925- isPost = false
930+ n = TThisParamNode ( c )
926931 )
927932 }
928933
929- predicate localFlowStep ( ClosureNode node1 , ClosureNode node2 ) {
930- exists ( CaptureContainer cc , BasicBlock bb1 , int i1 , BasicBlock bb2 , int i2 |
931- step ( cc , bb1 , i1 , bb2 , i2 ) and
932- ssaAccessAt ( node1 , pragma [ only_bind_into ] ( cc ) , _, bb1 , i1 ) and
933- ssaAccessAt ( node2 , pragma [ only_bind_into ] ( cc ) , false , bb2 , i2 )
934+ bindingset [ result , cc]
935+ pragma [ inline_late]
936+ private SsaFlow:: Node asNode ( CaptureContainer cc , ClosureNode n ) {
937+ n = TSynthSsa ( result )
938+ or
939+ exists ( BasicBlock bb , int i |
940+ result .( SsaFlow:: ExprNode ) .getExpr ( ) .hasCfgNode ( bb , i ) and
941+ ssaReadAt ( n , cc , false , bb , i )
934942 )
935943 or
936- exists ( CaptureContainer cc , BasicBlock bb , int i |
937- stepToPhi ( cc , bb , i , node2 ) and
938- ssaAccessAt ( node1 , cc , _ , bb , i )
944+ exists ( BasicBlock bb , int i |
945+ result . ( SsaFlow :: ExprPostUpdateNode ) . getExpr ( ) . hasCfgNode ( bb , i ) and
946+ ssaReadAt ( n , cc , true , bb , i )
939947 )
948+ or
949+ exists ( BasicBlock bb , int i |
950+ result .( SsaFlow:: WriteDefSourceNode ) .getDefinition ( ) .definesAt ( cc , bb , i ) and
951+ ssaWriteAt ( n , cc , bb , i )
952+ )
953+ }
954+
955+ cached
956+ predicate localFlowStep ( ClosureNode n1 , ClosureNode n2 ) {
957+ exists ( CaptureContainer cc | SsaFlow:: localFlowStep ( cc , asNode ( cc , n1 ) , asNode ( cc , n2 ) , _) )
940958 }
941959
942960 private predicate storeStepClosure (
0 commit comments