@@ -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
@@ -1594,6 +1700,44 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
1594
1700
newtype TApproxAccessPathFrontOption =
1595
1701
TApproxAccessPathFrontNone ( ) or
1596
1702
TApproxAccessPathFrontSome ( ApproxAccessPathFront apf )
1703
+
1704
+ cached
1705
+ newtype TNodeEx =
1706
+ TNodeNormal ( Node n ) or
1707
+ TNodeImplicitRead ( Node n ) or // will be restricted to nodes with actual implicit reads in `DataFlowImpl.qll`
1708
+ TParamReturnNode ( ParameterNode p , SndLevelScopeOption scope ) {
1709
+ paramReturnNode ( _, p , scope , _)
1710
+ }
1711
+
1712
+ /**
1713
+ * Holds if data can flow in one local step from `node1` to `node2`.
1714
+ */
1715
+ cached
1716
+ predicate localFlowStepExImpl ( NodeExImpl node1 , NodeExImpl node2 , string model ) {
1717
+ exists ( Node n1 , Node n2 |
1718
+ node1 .asNode ( ) = n1 and
1719
+ node2 .asNode ( ) = n2 and
1720
+ simpleLocalFlowStepExt ( pragma [ only_bind_into ] ( n1 ) , pragma [ only_bind_into ] ( n2 ) , model )
1721
+ )
1722
+ or
1723
+ exists ( Node n1 , Node n2 , SndLevelScopeOption scope |
1724
+ node1 .asNode ( ) = n1 and
1725
+ node2 = TParamReturnNode ( n2 , scope ) and
1726
+ paramReturnNode ( pragma [ only_bind_into ] ( n1 ) , pragma [ only_bind_into ] ( n2 ) ,
1727
+ pragma [ only_bind_into ] ( scope ) , _) and
1728
+ model = ""
1729
+ )
1730
+ }
1731
+
1732
+ cached
1733
+ ReturnPosition getReturnPositionEx ( NodeExImpl ret ) {
1734
+ result = getValueReturnPosition ( ret .asNode ( ) )
1735
+ or
1736
+ exists ( ParamNode p |
1737
+ ret = TParamReturnNode ( p , _) and
1738
+ result = getParamReturnPosition ( _, p )
1739
+ )
1740
+ }
1597
1741
}
1598
1742
1599
1743
bindingset [ call, tgt]
@@ -2177,36 +2321,6 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
2177
2321
nodeDataFlowType ( pragma [ only_bind_out ] ( n ) , pragma [ only_bind_into ] ( result ) )
2178
2322
}
2179
2323
2180
- pragma [ nomagic]
2181
- private predicate hasValueReturnKindIn ( ReturnNode ret , ReturnKindExt kind , DataFlowCallable c ) {
2182
- c = getNodeEnclosingCallable ( ret ) and
2183
- valueReturnNode ( ret , kind )
2184
- }
2185
-
2186
- pragma [ nomagic]
2187
- private predicate hasParamReturnKindIn (
2188
- PostUpdateNode n , ParamNode p , ReturnKindExt kind , DataFlowCallable c
2189
- ) {
2190
- c = getNodeEnclosingCallable ( n ) and
2191
- paramReturnNode ( n , p , _, kind )
2192
- }
2193
-
2194
- pragma [ nomagic]
2195
- ReturnPosition getValueReturnPosition ( ReturnNode ret ) {
2196
- exists ( ReturnKindExt kind , DataFlowCallable c |
2197
- hasValueReturnKindIn ( ret , kind , c ) and
2198
- result = TReturnPosition0 ( c , kind )
2199
- )
2200
- }
2201
-
2202
- pragma [ nomagic]
2203
- ReturnPosition getParamReturnPosition ( PostUpdateNode n , ParamNode p ) {
2204
- exists ( ReturnKindExt kind , DataFlowCallable c |
2205
- hasParamReturnKindIn ( n , p , kind , c ) and
2206
- result = TReturnPosition0 ( c , kind )
2207
- )
2208
- }
2209
-
2210
2324
/** An optional Boolean value. */
2211
2325
class BooleanOption extends TBooleanOption {
2212
2326
string toString ( ) {
0 commit comments