@@ -850,6 +850,85 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
850
850
851
851
class SndLevelScopeOption = SndLevelScopeOption:: Option ;
852
852
853
+ final class NodeExImpl extends TNodeEx {
854
+ string toString ( ) {
855
+ result = this .asNode ( ) .toString ( )
856
+ or
857
+ exists ( Node n | this .isImplicitReadNode ( n ) | result = n .toString ( ) + " [Ext]" )
858
+ or
859
+ result = this .asParamReturnNode ( ) .toString ( ) + " [Return]"
860
+ }
861
+
862
+ Node asNode ( ) { this = TNodeNormal ( result ) }
863
+
864
+ /** Gets the corresponding Node if this is a normal node or its post-implicit read node. */
865
+ Node asNodeOrImplicitRead ( ) { this = TNodeNormal ( result ) or this = TNodeImplicitRead ( result ) }
866
+
867
+ predicate isImplicitReadNode ( Node n ) { this = TNodeImplicitRead ( n ) }
868
+
869
+ ParameterNode asParamReturnNode ( ) { this = TParamReturnNode ( result , _) }
870
+
871
+ Node projectToNode ( ) {
872
+ this = TNodeNormal ( result ) or
873
+ this = TNodeImplicitRead ( result ) or
874
+ this = TParamReturnNode ( result , _)
875
+ }
876
+
877
+ pragma [ nomagic]
878
+ private DataFlowCallable getEnclosingCallable0 ( ) {
879
+ nodeEnclosingCallable ( this .projectToNode ( ) , result )
880
+ }
881
+
882
+ pragma [ inline]
883
+ DataFlowCallable getEnclosingCallable ( ) {
884
+ pragma [ only_bind_out ] ( this ) .getEnclosingCallable0 ( ) = pragma [ only_bind_into ] ( result )
885
+ }
886
+
887
+ pragma [ nomagic]
888
+ private DataFlowType getDataFlowType0 ( ) {
889
+ nodeDataFlowType ( this .asNode ( ) , result )
890
+ or
891
+ nodeDataFlowType ( this .asParamReturnNode ( ) , result )
892
+ }
893
+
894
+ pragma [ inline]
895
+ DataFlowType getDataFlowType ( ) {
896
+ pragma [ only_bind_out ] ( this ) .getDataFlowType0 ( ) = pragma [ only_bind_into ] ( result )
897
+ }
898
+
899
+ Location getLocation ( ) { result = this .projectToNode ( ) .getLocation ( ) }
900
+ }
901
+
902
+ final class ArgNodeExImpl extends NodeExImpl {
903
+ ArgNodeExImpl ( ) { this .asNode ( ) instanceof ArgNode }
904
+
905
+ DataFlowCall getCall ( ) { this .asNode ( ) .( ArgNode ) .argumentOf ( result , _) }
906
+ }
907
+
908
+ final class ParamNodeExImpl extends NodeExImpl {
909
+ ParamNodeExImpl ( ) { this .asNode ( ) instanceof ParamNode }
910
+
911
+ predicate isParameterOf ( DataFlowCallable c , ParameterPosition pos ) {
912
+ this .asNode ( ) .( ParamNode ) .isParameterOf ( c , pos )
913
+ }
914
+
915
+ ParameterPosition getPosition ( ) { this .isParameterOf ( _, result ) }
916
+ }
917
+
918
+ /**
919
+ * A node from which flow can return to the caller. This is either a regular
920
+ * `ReturnNode` or a synthesized node for flow out via a parameter.
921
+ */
922
+ final class RetNodeExImpl extends NodeExImpl {
923
+ private ReturnPosition pos ;
924
+
925
+ RetNodeExImpl ( ) { pos = getReturnPositionEx ( this ) }
926
+
927
+ ReturnPosition getReturnPosition ( ) { result = pos }
928
+
929
+ ReturnKindExt getKind ( ) { result = pos .getKind ( ) }
930
+ }
931
+
853
932
cached
854
933
private module Cached {
855
934
/**
@@ -927,11 +1006,8 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
927
1006
)
928
1007
}
929
1008
930
- cached
931
- predicate valueReturnNode ( ReturnNode n , ReturnKindExt k ) { k = TValueReturn ( n .getKind ( ) ) }
932
-
933
- cached
934
- predicate paramReturnNode (
1009
+ pragma [ nomagic]
1010
+ private predicate paramReturnNode (
935
1011
PostUpdateNode n , ParamNode p , SndLevelScopeOption scope , ReturnKindExt k
936
1012
) {
937
1013
exists ( ParameterPosition pos |
@@ -1541,6 +1617,20 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
1541
1617
1542
1618
class UnreachableSetOption = UnreachableSetOption:: Option ;
1543
1619
1620
+ pragma [ nomagic]
1621
+ private predicate hasValueReturnKindIn ( ReturnNode ret , ReturnKindExt kind , DataFlowCallable c ) {
1622
+ c = getNodeEnclosingCallable ( ret ) and
1623
+ kind = TValueReturn ( ret .getKind ( ) )
1624
+ }
1625
+
1626
+ pragma [ nomagic]
1627
+ private predicate hasParamReturnKindIn (
1628
+ PostUpdateNode n , ParamNode p , ReturnKindExt kind , DataFlowCallable c
1629
+ ) {
1630
+ c = getNodeEnclosingCallable ( n ) and
1631
+ paramReturnNode ( n , p , _, kind )
1632
+ }
1633
+
1544
1634
cached
1545
1635
newtype TReturnPosition =
1546
1636
TReturnPosition0 ( DataFlowCallable c , ReturnKindExt kind ) {
@@ -1549,6 +1639,22 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
1549
1639
hasParamReturnKindIn ( _, _, kind , c )
1550
1640
}
1551
1641
1642
+ cached
1643
+ ReturnPosition getValueReturnPosition ( ReturnNode ret ) {
1644
+ exists ( ReturnKindExt kind , DataFlowCallable c |
1645
+ hasValueReturnKindIn ( ret , kind , c ) and
1646
+ result = TReturnPosition0 ( c , kind )
1647
+ )
1648
+ }
1649
+
1650
+ cached
1651
+ ReturnPosition getParamReturnPosition ( PostUpdateNode n , ParamNode p ) {
1652
+ exists ( ReturnKindExt kind , DataFlowCallable c |
1653
+ hasParamReturnKindIn ( n , p , kind , c ) and
1654
+ result = TReturnPosition0 ( c , kind )
1655
+ )
1656
+ }
1657
+
1552
1658
cached
1553
1659
newtype TLocalFlowCallContext =
1554
1660
TAnyLocalCall ( ) or
@@ -1599,6 +1705,44 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
1599
1705
newtype TApproxAccessPathFrontOption =
1600
1706
TApproxAccessPathFrontNone ( ) or
1601
1707
TApproxAccessPathFrontSome ( ApproxAccessPathFront apf )
1708
+
1709
+ cached
1710
+ newtype TNodeEx =
1711
+ TNodeNormal ( Node n ) or
1712
+ TNodeImplicitRead ( Node n ) or // will be restricted to nodes with actual implicit reads in `DataFlowImpl.qll`
1713
+ TParamReturnNode ( ParameterNode p , SndLevelScopeOption scope ) {
1714
+ paramReturnNode ( _, p , scope , _)
1715
+ }
1716
+
1717
+ /**
1718
+ * Holds if data can flow in one local step from `node1` to `node2`.
1719
+ */
1720
+ cached
1721
+ predicate localFlowStepExImpl ( NodeExImpl node1 , NodeExImpl node2 , string model ) {
1722
+ exists ( Node n1 , Node n2 |
1723
+ node1 .asNode ( ) = n1 and
1724
+ node2 .asNode ( ) = n2 and
1725
+ simpleLocalFlowStepExt ( pragma [ only_bind_into ] ( n1 ) , pragma [ only_bind_into ] ( n2 ) , model )
1726
+ )
1727
+ or
1728
+ exists ( Node n1 , Node n2 , SndLevelScopeOption scope |
1729
+ node1 .asNode ( ) = n1 and
1730
+ node2 = TParamReturnNode ( n2 , scope ) and
1731
+ paramReturnNode ( pragma [ only_bind_into ] ( n1 ) , pragma [ only_bind_into ] ( n2 ) ,
1732
+ pragma [ only_bind_into ] ( scope ) , _) and
1733
+ model = ""
1734
+ )
1735
+ }
1736
+
1737
+ cached
1738
+ ReturnPosition getReturnPositionEx ( NodeExImpl ret ) {
1739
+ result = getValueReturnPosition ( ret .asNode ( ) )
1740
+ or
1741
+ exists ( ParamNode p |
1742
+ ret = TParamReturnNode ( p , _) and
1743
+ result = getParamReturnPosition ( _, p )
1744
+ )
1745
+ }
1602
1746
}
1603
1747
1604
1748
bindingset [ call, tgt]
@@ -2182,36 +2326,6 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
2182
2326
nodeDataFlowType ( pragma [ only_bind_out ] ( n ) , pragma [ only_bind_into ] ( result ) )
2183
2327
}
2184
2328
2185
- pragma [ nomagic]
2186
- private predicate hasValueReturnKindIn ( ReturnNode ret , ReturnKindExt kind , DataFlowCallable c ) {
2187
- c = getNodeEnclosingCallable ( ret ) and
2188
- valueReturnNode ( ret , kind )
2189
- }
2190
-
2191
- pragma [ nomagic]
2192
- private predicate hasParamReturnKindIn (
2193
- PostUpdateNode n , ParamNode p , ReturnKindExt kind , DataFlowCallable c
2194
- ) {
2195
- c = getNodeEnclosingCallable ( n ) and
2196
- paramReturnNode ( n , p , _, kind )
2197
- }
2198
-
2199
- pragma [ nomagic]
2200
- ReturnPosition getValueReturnPosition ( ReturnNode ret ) {
2201
- exists ( ReturnKindExt kind , DataFlowCallable c |
2202
- hasValueReturnKindIn ( ret , kind , c ) and
2203
- result = TReturnPosition0 ( c , kind )
2204
- )
2205
- }
2206
-
2207
- pragma [ nomagic]
2208
- ReturnPosition getParamReturnPosition ( PostUpdateNode n , ParamNode p ) {
2209
- exists ( ReturnKindExt kind , DataFlowCallable c |
2210
- hasParamReturnKindIn ( n , p , kind , c ) and
2211
- result = TReturnPosition0 ( c , kind )
2212
- )
2213
- }
2214
-
2215
2329
/** An optional Boolean value. */
2216
2330
class BooleanOption extends TBooleanOption {
2217
2331
string toString ( ) {
0 commit comments