@@ -318,8 +318,8 @@ private module Cached {
318318 } or
319319 TSynthSplatParameterElementNode ( DataFlowCallable c , int n ) {
320320 exists ( c .asCallable ( ) ) and // exclude library callables
321- exists ( ArgumentPosition p | p .isPositional ( n ) ) and
322- isParameterNode ( _ , c , any ( ParameterPosition p | p . isSplat ( _ ) ) )
321+ isParameterNode ( _ , c , any ( ParameterPosition p | p .isSplat ( _ ) ) ) and
322+ n in [ 0 .. 10 ]
323323 } or
324324 TExprPostUpdateNode ( CfgNodes:: ExprCfgNode n ) {
325325 // filter out nodes that clearly don't need post-update nodes
@@ -892,7 +892,20 @@ private module ParameterNodes {
892892
893893 SynthSplatParameterElementNode ( ) { this = TSynthSplatParameterElementNode ( callable , pos ) }
894894
895- int getPosition ( ) { result = pos }
895+ pragma [ nomagic]
896+ NormalParameterNode getSplatParameterNode ( int splatPos ) {
897+ result
898+ .isParameterOf ( this .getEnclosingCallable ( ) , any ( ParameterPosition p | p .isSplat ( splatPos ) ) )
899+ }
900+
901+ int getStorePosition ( ) { result = pos }
902+
903+ int getReadPosition ( ) {
904+ exists ( int splatPos |
905+ exists ( this .getSplatParameterNode ( splatPos ) ) and
906+ result = pos + splatPos
907+ )
908+ }
896909
897910 final override Parameter getParameter ( ) { none ( ) }
898911
@@ -1070,14 +1083,14 @@ private module ArgumentNodes {
10701083 * 2. We match this to an analogous parameter node `SynthSplatArgParameterNode` on the callee side
10711084 * (see `parameterMatch`).
10721085 * 3. For each content element stored in the `SynthSplatArgParameterNode`, we add a read step to a separate
1073- * `SynthSplatParameterElementNode`, which is parameterised by the element index (see `readStep`).
1086+ * `SynthSplatParameterElementNode`, which is parameterized by the element index (see `readStep`).
10741087 * 4. Finally, we add store steps from these `SynthSplatParameterElementNode`s to the real splat parameter node
10751088 * (see `storeStep`).
10761089 * We only add store steps for elements that will not flow to the earlier positional parameters.
10771090 * In practice that means we ignore elements at index `<= N`, where `N` is the index of the splat parameter.
10781091 * For the remaining elements we subtract `N` from their index and store them in the splat parameter.
10791092 */
1080- class SynthSplatArgumentNode extends ArgumentNode , TSynthSplatArgumentNode {
1093+ class SynthSplatArgumentNode extends ArgumentNode , NodeImpl , TSynthSplatArgumentNode {
10811094 CfgNodes:: ExprNodes:: CallCfgNode c ;
10821095
10831096 SynthSplatArgumentNode ( ) { this = TSynthSplatArgumentNode ( c ) }
@@ -1090,12 +1103,6 @@ private module ArgumentNodes {
10901103 call = c and
10911104 pos .isSynthSplat ( )
10921105 }
1093- }
1094-
1095- private class SynthSplatArgumentNodeImpl extends NodeImpl , TSynthSplatArgumentNode {
1096- CfgNodes:: ExprNodes:: CallCfgNode c ;
1097-
1098- SynthSplatArgumentNodeImpl ( ) { this = TSynthSplatArgumentNode ( c ) }
10991106
11001107 override CfgScope getCfgScope ( ) { result = c .getExpr ( ) .getCfgScope ( ) }
11011108
@@ -1346,16 +1353,11 @@ predicate storeStepCommon(Node node1, ContentSet c, Node node2) {
13461353 exists ( int n | pos .isPositional ( n ) and c = getPositionalContent ( n ) )
13471354 )
13481355 or
1349- // Store from SynthSplatParameterElementNode[n] into SplatParameterNode[m]
1350- // where m = n - <position of SplatParameterNode>
1351- exists ( SynthSplatParameterElementNode elemNode , NormalParameterNode splatNode , int splatPos |
1352- elemNode = node1 and splatNode = node2
1353- |
1354- splatNode
1355- .isParameterOf ( elemNode .getEnclosingCallable ( ) ,
1356- any ( ParameterPosition p | p .isSplat ( splatPos ) ) ) and
1357- c = getPositionalContent ( elemNode .getPosition ( ) - splatPos )
1358- )
1356+ node1 =
1357+ any ( SynthSplatParameterElementNode elemNode |
1358+ node2 = elemNode .getSplatParameterNode ( _) and
1359+ c = getPositionalContent ( elemNode .getStorePosition ( ) )
1360+ )
13591361}
13601362
13611363/**
@@ -1421,19 +1423,17 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
14211423 or
14221424 node2 = node1 .( SynthHashSplatParameterNode ) .getAKeywordParameter ( c )
14231425 or
1424- node2 = node1 .( SynthSplatParameterNode ) .getAParameter ( c )
1425- or
14261426 FlowSummaryImpl:: Private:: Steps:: summaryReadStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) , c ,
14271427 node2 .( FlowSummaryNode ) .getSummaryNode ( ) )
14281428 or
1429+ node2 = node1 .( SynthSplatParameterNode ) .getAParameter ( c )
1430+ or
14291431 // Read from SynthSplatArgParameterNode into SynthSplatParameterElementNode
1430- exists ( SynthSplatArgParameterNode fromNode , SynthSplatParameterElementNode toNode , int pos |
1431- node1 = fromNode and node2 = toNode
1432- |
1433- fromNode .isParameterOf ( toNode .getEnclosingCallable ( ) , _) and
1434- c = getPositionalContent ( pos ) and
1435- toNode .getPosition ( ) = pos
1436- )
1432+ node2 =
1433+ any ( SynthSplatParameterElementNode e |
1434+ node1 .( SynthSplatArgParameterNode ) .isParameterOf ( e .getEnclosingCallable ( ) , _) and
1435+ c = getPositionalContent ( e .getReadPosition ( ) )
1436+ )
14371437}
14381438
14391439/**
0 commit comments