@@ -14,6 +14,11 @@ private module Cached {
14
14
ReturnStep ( ) or
15
15
StoreStep ( TypeTrackerContent content ) { basicStoreStep ( _, _, content ) } or
16
16
LoadStep ( TypeTrackerContent content ) { basicLoadStep ( _, _, content ) } or
17
+ LoadStoreStep ( TypeTrackerContent load , TypeTrackerContent store ) {
18
+ basicLoadStoreStep ( _, _, load , store )
19
+ } or
20
+ WithContent ( ContentFilter filter ) { basicWithContentStep ( _, _, filter ) } or
21
+ WithoutContent ( ContentFilter filter ) { basicWithoutContentStep ( _, _, filter ) } or
17
22
JumpStep ( )
18
23
19
24
cached
@@ -61,6 +66,14 @@ private module Cached {
61
66
or
62
67
step = JumpStep ( ) and
63
68
result = MkTypeTracker ( false , currentContents )
69
+ or
70
+ exists ( ContentFilter filter | result = tt |
71
+ step = WithContent ( filter ) and
72
+ currentContents = filter .getAMatchingContent ( )
73
+ or
74
+ step = WithoutContent ( filter ) and
75
+ not currentContents = filter .getAMatchingContent ( )
76
+ )
64
77
)
65
78
or
66
79
exists ( TypeTrackerContent storeContents , boolean hasCall |
@@ -75,6 +88,16 @@ private module Cached {
75
88
tt = noContentTypeTracker ( hasCall ) and
76
89
result = MkTypeTracker ( hasCall , storeContents )
77
90
)
91
+ or
92
+ exists (
93
+ TypeTrackerContent currentContent , TypeTrackerContent store , TypeTrackerContent load ,
94
+ boolean hasCall
95
+ |
96
+ step = LoadStoreStep ( pragma [ only_bind_into ] ( load ) , pragma [ only_bind_into ] ( store ) ) and
97
+ compatibleContents ( pragma [ only_bind_into ] ( currentContent ) , load ) and
98
+ tt = MkTypeTracker ( pragma [ only_bind_into ] ( hasCall ) , currentContent ) and
99
+ result = MkTypeTracker ( pragma [ only_bind_out ] ( hasCall ) , store )
100
+ )
78
101
}
79
102
80
103
pragma [ nomagic]
@@ -96,6 +119,14 @@ private module Cached {
96
119
or
97
120
step = JumpStep ( ) and
98
121
result = MkTypeBackTracker ( false , content )
122
+ or
123
+ exists ( ContentFilter filter | result = tbt |
124
+ step = WithContent ( filter ) and
125
+ content = filter .getAMatchingContent ( )
126
+ or
127
+ step = WithoutContent ( filter ) and
128
+ not content = filter .getAMatchingContent ( )
129
+ )
99
130
)
100
131
or
101
132
exists ( TypeTrackerContent loadContents , boolean hasReturn |
@@ -110,6 +141,16 @@ private module Cached {
110
141
tbt = noContentTypeBackTracker ( hasReturn ) and
111
142
result = MkTypeBackTracker ( hasReturn , loadContents )
112
143
)
144
+ or
145
+ exists (
146
+ TypeTrackerContent currentContent , TypeTrackerContent store , TypeTrackerContent load ,
147
+ boolean hasCall
148
+ |
149
+ step = LoadStoreStep ( pragma [ only_bind_into ] ( load ) , pragma [ only_bind_into ] ( store ) ) and
150
+ compatibleContents ( store , pragma [ only_bind_into ] ( currentContent ) ) and
151
+ tbt = MkTypeBackTracker ( pragma [ only_bind_into ] ( hasCall ) , currentContent ) and
152
+ result = MkTypeBackTracker ( pragma [ only_bind_out ] ( hasCall ) , load )
153
+ )
113
154
}
114
155
115
156
/**
@@ -146,6 +187,19 @@ private module Cached {
146
187
or
147
188
basicLoadStep ( nodeFrom , nodeTo , content ) and summary = LoadStep ( content )
148
189
)
190
+ or
191
+ exists ( TypeTrackerContent loadContent , TypeTrackerContent storeContent |
192
+ flowsToLoadStoreStep ( nodeFrom , nodeTo , loadContent , storeContent ) and
193
+ summary = LoadStoreStep ( loadContent , storeContent )
194
+ )
195
+ or
196
+ exists ( ContentFilter filter |
197
+ basicWithContentStep ( nodeFrom , nodeTo , filter ) and
198
+ summary = WithContent ( filter )
199
+ or
200
+ basicWithoutContentStep ( nodeFrom , nodeTo , filter ) and
201
+ summary = WithoutContent ( filter )
202
+ )
149
203
}
150
204
151
205
cached
@@ -190,6 +244,18 @@ private predicate flowsToStoreStep(
190
244
exists ( Node obj | nodeTo .flowsTo ( obj ) and basicStoreStep ( nodeFrom , obj , content ) )
191
245
}
192
246
247
+ /**
248
+ * Holds if `loadContent` is loaded from `nodeFrom` and written to `storeContent` of `nodeTo`.
249
+ */
250
+ predicate flowsToLoadStoreStep (
251
+ Node nodeFrom , TypeTrackingNode nodeTo , TypeTrackerContent loadContent ,
252
+ TypeTrackerContent storeContent
253
+ ) {
254
+ exists ( Node obj |
255
+ nodeTo .flowsTo ( obj ) and basicLoadStoreStep ( nodeFrom , obj , loadContent , storeContent )
256
+ )
257
+ }
258
+
193
259
/**
194
260
* INTERNAL: Use `TypeTracker` or `TypeBackTracker` instead.
195
261
*
@@ -208,6 +274,11 @@ class StepSummary extends TStepSummary {
208
274
or
209
275
exists ( TypeTrackerContent content | this = LoadStep ( content ) | result = "load " + content )
210
276
or
277
+ exists ( TypeTrackerContent load , TypeTrackerContent store |
278
+ this = LoadStoreStep ( load , store ) and
279
+ result = "load-store " + load + " -> " + store
280
+ )
281
+ or
211
282
this instanceof JumpStep and result = "jump"
212
283
}
213
284
}
0 commit comments