@@ -11,12 +11,31 @@ class Node = DataFlowPublic::Node;
11
11
12
12
class TypeTrackingNode = DataFlowPublic:: LocalSourceNode ;
13
13
14
+ /** Holds if there is a simple local flow step from `nodeFrom` to `nodeTo` */
14
15
predicate simpleLocalFlowStep = DataFlowPrivate:: localFlowStepTypeTracker / 2 ;
15
16
17
+ /**
18
+ * Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
19
+ */
16
20
predicate jumpStep = DataFlowPrivate:: jumpStep / 2 ;
17
21
18
- /** Holds if there is a level step from `pred` to `succ`. */
19
- predicate levelStep ( Node pred , Node succ ) { none ( ) }
22
+ /**
23
+ * Holds if there is a summarized local flow step from `nodeFrom` to `nodeTo`,
24
+ * because there is direct flow from a parameter to a return. That is, summarized
25
+ * steps are not applied recursively.
26
+ */
27
+ pragma [ nomagic]
28
+ private predicate summarizedLocalStep ( Node nodeFrom , Node nodeTo ) {
29
+ exists ( DataFlowPublic:: ParameterNode param , DataFlowPrivate:: ReturningNode returnNode |
30
+ DataFlowPrivate:: LocalFlow:: getParameterDefNode ( param .getParameter ( ) )
31
+ .( TypeTrackingNode )
32
+ .flowsTo ( returnNode ) and
33
+ callStep ( nodeTo .asExpr ( ) , nodeFrom , param )
34
+ )
35
+ }
36
+
37
+ /** Holds if there is a level step from `nodeFrom` to `nodeTo`. */
38
+ predicate levelStep ( Node nodeFrom , Node nodeTo ) { summarizedLocalStep ( nodeFrom , nodeTo ) }
20
39
21
40
/**
22
41
* Gets the name of a possible piece of content. This will usually include things like
@@ -48,6 +67,13 @@ private predicate viableParam(
48
67
)
49
68
}
50
69
70
+ private predicate callStep ( ExprNodes:: CallCfgNode call , Node nodeFrom , Node nodeTo ) {
71
+ exists ( DataFlowDispatch:: ParameterPosition pos |
72
+ argumentPositionMatch ( call , nodeFrom , pos ) and
73
+ viableParam ( call , nodeTo , pos )
74
+ )
75
+ }
76
+
51
77
/**
52
78
* Holds if `nodeFrom` steps to `nodeTo` by being passed as a parameter in a call.
53
79
*
@@ -56,10 +82,7 @@ private predicate viableParam(
56
82
* methods is done using API graphs (which uses type tracking).
57
83
*/
58
84
predicate callStep ( Node nodeFrom , Node nodeTo ) {
59
- exists ( ExprNodes:: CallCfgNode call , DataFlowDispatch:: ParameterPosition pos |
60
- argumentPositionMatch ( call , nodeFrom , pos ) and
61
- viableParam ( call , nodeTo , pos )
62
- )
85
+ callStep ( _, nodeFrom , nodeTo )
63
86
or
64
87
// In normal data-flow, this will be a local flow step. But for type tracking
65
88
// we model it as a call step, in order to avoid computing a potential
0 commit comments