@@ -76,17 +76,16 @@ module SsaFlow {
76
76
or
77
77
result .( Impl:: ExprNode ) .getExpr ( ) = n .asStmt ( )
78
78
or
79
- result .( Impl:: ExprNode ) .getExpr ( ) = n .( ProcessNode ) .getProcessBlock ( )
79
+ result .( Impl:: ExprNode ) .getExpr ( ) =
80
+ [ n .( ProcessNode ) .getProcessBlock ( ) , n .( ProcessPropertyByNameNode ) .getProcessBlock ( ) ]
80
81
or
81
82
result .( Impl:: ExprPostUpdateNode ) .getExpr ( ) = n .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( )
82
83
or
83
84
n = toParameterNode ( result .( Impl:: ParameterNode ) .getParameter ( ) )
84
85
}
85
86
86
87
predicate localFlowStep ( SsaImpl:: DefinitionExt def , Node nodeFrom , Node nodeTo , boolean isUseStep ) {
87
- Impl:: localFlowStep ( def , asNode ( nodeFrom ) , asNode ( nodeTo ) , isUseStep ) and
88
- // Flow out of property name parameter nodes are covered by `readStep`.
89
- not nodeFrom instanceof PipelineByPropertyNameParameter
88
+ Impl:: localFlowStep ( def , asNode ( nodeFrom ) , asNode ( nodeTo ) , isUseStep )
90
89
}
91
90
92
91
predicate localMustFlowStep ( SsaImpl:: DefinitionExt def , Node nodeFrom , Node nodeTo ) {
@@ -146,6 +145,12 @@ module VariableCapture {
146
145
// TODO
147
146
}
148
147
148
+ private predicate isProcessPropertyByNameNode (
149
+ PipelineByPropertyNameIteratorVariable iter , ProcessBlock pb
150
+ ) {
151
+ pb .getEnclosingScope ( ) = iter .getDeclaringScope ( )
152
+ }
153
+
149
154
/** A collection of cached types and predicates to be evaluated in the same stage. */
150
155
cached
151
156
private module Cached {
@@ -172,7 +177,10 @@ private module Cached {
172
177
TPreReturnNodeImpl ( CfgNodes:: AstCfgNode n , Boolean isArray ) { isMultiReturned ( n ) } or
173
178
TImplicitWrapNode ( CfgNodes:: AstCfgNode n , Boolean shouldWrap ) { isMultiReturned ( n ) } or
174
179
TReturnNodeImpl ( CfgScope scope ) or
175
- TProcessNode ( ProcessBlock process )
180
+ TProcessNode ( ProcessBlock process ) or
181
+ TProcessPropertyByNameNode ( PipelineByPropertyNameIteratorVariable iter ) {
182
+ isProcessPropertyByNameNode ( iter , _)
183
+ }
176
184
177
185
cached
178
186
Location getLocation ( NodeImpl n ) { result = n .getLocationImpl ( ) }
@@ -501,8 +509,8 @@ private module ParameterNodes {
501
509
override string toStringImpl ( ) { result = parameter .toString ( ) }
502
510
}
503
511
504
- class PipelineByPropertyNameParameter extends NormalParameterNode {
505
- PipelineByPropertyNameParameter ( ) { this .getParameter ( ) .isPipelineByPropertyName ( ) }
512
+ class PipelineByPropertyNameParameterNode extends NormalParameterNode {
513
+ PipelineByPropertyNameParameterNode ( ) { this .getParameter ( ) .isPipelineByPropertyName ( ) }
506
514
507
515
string getPropretyName ( ) { result = this .getParameter ( ) .getName ( ) }
508
516
}
@@ -753,15 +761,30 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
753
761
)
754
762
or
755
763
c .isAnyElement ( ) and
756
- exists ( SsaImpl:: DefinitionExt def |
757
- node1 .( ProcessNode ) .getIteratorVariable ( ) = def .getSourceVariable ( ) and
764
+ exists ( SsaImpl:: DefinitionExt def , ProcessNode processNode , LocalScopeVariable iterator |
765
+ processNode = node1 and iterator = def .getSourceVariable ( )
766
+ |
767
+ processNode .getIteratorVariable ( ) = iterator and
768
+ SsaImpl:: firstRead ( def , node2 .asExpr ( ) )
769
+ or
770
+ processNode .getPropertyNameIteratorVariable ( ) = iterator and
771
+ node2 = TProcessPropertyByNameNode ( def .getSourceVariable ( ) )
772
+ )
773
+ or
774
+ exists (
775
+ Content:: KnownElementContent ec , PipelineByPropertyNameParameter p , SsaImpl:: DefinitionExt def
776
+ |
777
+ c .isSingleton ( ec ) and
778
+ p .getIteratorVariable ( ) = node1 .( ProcessPropertyByNameNode ) .getVariable ( ) and
779
+ p .getName ( ) = ec .getIndex ( ) .asString ( ) and
780
+ def .getSourceVariable ( ) = p .getIteratorVariable ( ) and
758
781
SsaImpl:: firstRead ( def , node2 .asExpr ( ) )
759
782
)
760
783
or
761
784
exists ( Content:: KnownElementContent ec , SsaImpl:: DefinitionExt def |
762
785
c .isSingleton ( ec ) and
763
- node1 .( PipelineByPropertyNameParameter ) .getPropretyName ( ) = ec .getIndex ( ) .asString ( ) and
764
- def .getSourceVariable ( ) = node1 .( PipelineByPropertyNameParameter ) .getParameter ( ) and
786
+ node1 .( PipelineByPropertyNameParameterNode ) .getPropretyName ( ) = ec .getIndex ( ) .asString ( ) and
787
+ def .getSourceVariable ( ) = node1 .( PipelineByPropertyNameParameterNode ) .getParameter ( ) and
765
788
SsaImpl:: firstRead ( def , node2 .asExpr ( ) )
766
789
)
767
790
}
@@ -792,11 +815,6 @@ predicate expectsContent(Node n, ContentSet c) {
792
815
or
793
816
n instanceof ProcessNode and
794
817
c .isAnyElement ( )
795
- or
796
- exists ( Content:: KnownElementContent ec |
797
- ec .getIndex ( ) .asString ( ) = n .( PipelineByPropertyNameParameter ) .getPropretyName ( ) and
798
- c .isSingleton ( ec )
799
- )
800
818
}
801
819
802
820
class DataFlowType extends TDataFlowType {
@@ -925,15 +943,39 @@ private class ProcessNode extends TProcessNode, NodeImpl {
925
943
926
944
override Location getLocationImpl ( ) { result = process .getLocation ( ) }
927
945
928
- override string toStringImpl ( ) { result = process .toString ( ) }
946
+ override string toStringImpl ( ) { result = "process node for " + process .toString ( ) }
929
947
930
948
override predicate nodeIsHidden ( ) { any ( ) }
931
949
932
950
PipelineIteratorVariable getIteratorVariable ( ) { result .getProcessBlock ( ) = process }
933
951
952
+ PipelineByPropertyNameIteratorVariable getPropertyNameIteratorVariable ( ) {
953
+ result .getProcessBlock ( ) = process
954
+ }
955
+
934
956
CfgNodes:: ProcessBlockCfgNode getProcessBlock ( ) { result .getAstNode ( ) = process }
935
957
}
936
958
959
+ private class ProcessPropertyByNameNode extends TProcessPropertyByNameNode , NodeImpl {
960
+ private PipelineByPropertyNameIteratorVariable iter ;
961
+
962
+ ProcessPropertyByNameNode ( ) { this = TProcessPropertyByNameNode ( iter ) }
963
+
964
+ PipelineByPropertyNameIteratorVariable getVariable ( ) { result = iter }
965
+
966
+ override CfgScope getCfgScope ( ) { result = iter .getDeclaringScope ( ) }
967
+
968
+ override Location getLocationImpl ( ) { result = iter .getLocation ( ) }
969
+
970
+ override string toStringImpl ( ) { result = "process node for " + iter .toString ( ) }
971
+
972
+ override predicate nodeIsHidden ( ) { any ( ) }
973
+
974
+ CfgNodes:: ProcessBlockCfgNode getProcessBlock ( ) {
975
+ isProcessPropertyByNameNode ( iter , result .getAstNode ( ) )
976
+ }
977
+ }
978
+
937
979
/** A node that performs a type cast. */
938
980
class CastNode extends Node {
939
981
CastNode ( ) { none ( ) }
0 commit comments