@@ -699,6 +699,7 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
699
699
class SourceVariable = CaptureContainer ;
700
700
701
701
predicate variableWrite ( BasicBlock bb , int i , SourceVariable cc , boolean certain ) {
702
+ Cached:: ref ( ) and
702
703
(
703
704
exists ( CapturedVariable v | cc = TVariable ( v ) and captureWrite ( v , bb , i , true , _) )
704
705
or
@@ -721,23 +722,55 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
721
722
722
723
private module CaptureSsa = Ssa:: Make< Location , CaptureSsaInput > ;
723
724
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
741
774
742
775
class ClosureNode extends TClosureNode {
743
776
/** Gets a textual representation of this node. */
@@ -746,11 +779,7 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
746
779
or
747
780
result = "this" and this = TSynthThisQualifier ( _, _, _)
748
781
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 ( ) )
754
783
or
755
784
exists ( Expr expr , boolean isPost | this = TExprNode ( expr , isPost ) |
756
785
isPost = false and result = expr .toString ( )
@@ -784,9 +813,7 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
784
813
captureWrite ( _, bb , i , false , any ( VariableWrite vw | result = vw .getLocation ( ) ) )
785
814
)
786
815
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 ( ) )
790
817
or
791
818
exists ( Expr expr | this = TExprNode ( expr , _) and result = expr .getLocation ( ) )
792
819
or
@@ -802,35 +829,29 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
802
829
}
803
830
}
804
831
805
- private class TSynthesizedCaptureNode = TSynthRead or TSynthThisQualifier or TSynthPhi ;
832
+ private class TSynthesizedCaptureNode = TSynthRead or TSynthThisQualifier or TSynthSsa ;
806
833
807
834
class SynthesizedCaptureNode extends ClosureNode , TSynthesizedCaptureNode {
808
835
BasicBlock getBasicBlock ( ) {
809
836
this = TSynthRead ( _, result , _, _)
810
837
or
811
838
this = TSynthThisQualifier ( result , _, _)
812
839
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 )
816
841
}
817
842
818
843
Callable getEnclosingCallable ( ) { result = this .getBasicBlock ( ) .getEnclosingCallable ( ) }
819
844
820
845
predicate isVariableAccess ( CapturedVariable v ) {
821
846
this = TSynthRead ( v , _, _, _)
822
847
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 ) )
826
849
}
827
850
828
851
predicate isInstanceAccess ( ) {
829
852
this instanceof TSynthThisQualifier
830
853
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 ( _) )
834
855
}
835
856
}
836
857
@@ -872,18 +893,7 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
872
893
)
873
894
}
874
895
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 (
887
897
ClosureNode n , CaptureContainer cc , boolean isPost , BasicBlock bb , int i
888
898
) {
889
899
exists ( CapturedVariable v |
@@ -894,49 +904,57 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
894
904
or
895
905
n = TSynthThisQualifier ( bb , i , isPost ) and cc = TThis ( bb .getEnclosingCallable ( ) )
896
906
or
897
- exists ( CaptureSsa:: DefinitionExt phi |
898
- n = TSynthPhi ( phi ) and phi .definesAt ( cc , bb , i , _) and isPost = false
899
- )
900
- or
901
907
exists ( VariableRead vr , CapturedVariable v |
902
908
captureRead ( v , bb , i , true , vr ) and
903
909
n = TExprNode ( vr , isPost ) and
904
910
cc = TVariable ( v )
905
911
)
906
- or
912
+ }
913
+
914
+ private predicate ssaWriteAt ( ClosureNode n , CaptureContainer cc , BasicBlock bb , int i ) {
907
915
exists ( VariableWrite vw , CapturedVariable v |
908
916
captureWrite ( v , bb , i , true , vw ) and
909
917
n = TVariableWriteSourceNode ( vw ) and
910
- isPost = false and
911
918
cc = TVariable ( v )
912
919
)
913
920
or
914
921
exists ( CapturedParameter p |
915
922
entryDef ( cc , bb , i ) and
916
923
cc = TVariable ( p ) and
917
- n = TParamNode ( p ) and
918
- isPost = false
924
+ n = TParamNode ( p )
919
925
)
920
926
or
921
927
exists ( Callable c |
922
928
entryDef ( cc , bb , i ) and
923
929
cc = TThis ( c ) and
924
- n = TThisParamNode ( c ) and
925
- isPost = false
930
+ n = TThisParamNode ( c )
926
931
)
927
932
}
928
933
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 )
934
942
)
935
943
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 )
939
947
)
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 ) , _) )
940
958
}
941
959
942
960
private predicate storeStepClosure (
0 commit comments