@@ -14,6 +14,11 @@ private module Cached {
1414 ReturnStep ( ) or
1515 StoreStep ( TypeTrackerContent content ) { basicStoreStep ( _, _, content ) } or
1616 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
1722 JumpStep ( )
1823
1924 cached
@@ -25,7 +30,11 @@ private module Cached {
2530 // We can't rely on `basicStoreStep` since `startInContent` might be used with
2631 // a content that has no corresponding store.
2732 exists ( TypeTrackerContent loadContents |
28- basicLoadStep ( _, _, loadContents ) and
33+ (
34+ basicLoadStep ( _, _, loadContents )
35+ or
36+ basicLoadStoreStep ( _, _, loadContents , _)
37+ ) and
2938 compatibleContents ( content , loadContents )
3039 )
3140 }
@@ -37,7 +46,11 @@ private module Cached {
3746 or
3847 // As in MkTypeTracker, restrict `content` to those that might eventually match a store.
3948 exists ( TypeTrackerContent storeContent |
40- basicStoreStep ( _, _, storeContent ) and
49+ (
50+ basicStoreStep ( _, _, storeContent )
51+ or
52+ basicLoadStoreStep ( _, _, _, storeContent )
53+ ) and
4154 compatibleContents ( storeContent , content )
4255 )
4356 }
@@ -61,6 +74,14 @@ private module Cached {
6174 or
6275 step = JumpStep ( ) and
6376 result = MkTypeTracker ( false , currentContents )
77+ or
78+ exists ( ContentFilter filter | result = tt |
79+ step = WithContent ( filter ) and
80+ currentContents = filter .getAMatchingContent ( )
81+ or
82+ step = WithoutContent ( filter ) and
83+ not currentContents = filter .getAMatchingContent ( )
84+ )
6485 )
6586 or
6687 exists ( TypeTrackerContent storeContents , boolean hasCall |
@@ -75,6 +96,16 @@ private module Cached {
7596 tt = noContentTypeTracker ( hasCall ) and
7697 result = MkTypeTracker ( hasCall , storeContents )
7798 )
99+ or
100+ exists (
101+ TypeTrackerContent currentContent , TypeTrackerContent store , TypeTrackerContent load ,
102+ boolean hasCall
103+ |
104+ step = LoadStoreStep ( pragma [ only_bind_into ] ( load ) , pragma [ only_bind_into ] ( store ) ) and
105+ compatibleContents ( pragma [ only_bind_into ] ( currentContent ) , load ) and
106+ tt = MkTypeTracker ( pragma [ only_bind_into ] ( hasCall ) , currentContent ) and
107+ result = MkTypeTracker ( pragma [ only_bind_out ] ( hasCall ) , store )
108+ )
78109 }
79110
80111 pragma [ nomagic]
@@ -96,6 +127,14 @@ private module Cached {
96127 or
97128 step = JumpStep ( ) and
98129 result = MkTypeBackTracker ( false , content )
130+ or
131+ exists ( ContentFilter filter | result = tbt |
132+ step = WithContent ( filter ) and
133+ content = filter .getAMatchingContent ( )
134+ or
135+ step = WithoutContent ( filter ) and
136+ not content = filter .getAMatchingContent ( )
137+ )
99138 )
100139 or
101140 exists ( TypeTrackerContent loadContents , boolean hasReturn |
@@ -110,6 +149,16 @@ private module Cached {
110149 tbt = noContentTypeBackTracker ( hasReturn ) and
111150 result = MkTypeBackTracker ( hasReturn , loadContents )
112151 )
152+ or
153+ exists (
154+ TypeTrackerContent currentContent , TypeTrackerContent store , TypeTrackerContent load ,
155+ boolean hasCall
156+ |
157+ step = LoadStoreStep ( pragma [ only_bind_into ] ( load ) , pragma [ only_bind_into ] ( store ) ) and
158+ compatibleContents ( store , pragma [ only_bind_into ] ( currentContent ) ) and
159+ tbt = MkTypeBackTracker ( pragma [ only_bind_into ] ( hasCall ) , currentContent ) and
160+ result = MkTypeBackTracker ( pragma [ only_bind_out ] ( hasCall ) , load )
161+ )
113162 }
114163
115164 /**
@@ -146,6 +195,19 @@ private module Cached {
146195 or
147196 basicLoadStep ( nodeFrom , nodeTo , content ) and summary = LoadStep ( content )
148197 )
198+ or
199+ exists ( TypeTrackerContent loadContent , TypeTrackerContent storeContent |
200+ flowsToLoadStoreStep ( nodeFrom , nodeTo , loadContent , storeContent ) and
201+ summary = LoadStoreStep ( loadContent , storeContent )
202+ )
203+ or
204+ exists ( ContentFilter filter |
205+ basicWithContentStep ( nodeFrom , nodeTo , filter ) and
206+ summary = WithContent ( filter )
207+ or
208+ basicWithoutContentStep ( nodeFrom , nodeTo , filter ) and
209+ summary = WithoutContent ( filter )
210+ )
149211 }
150212
151213 cached
@@ -190,6 +252,18 @@ private predicate flowsToStoreStep(
190252 exists ( Node obj | nodeTo .flowsTo ( obj ) and basicStoreStep ( nodeFrom , obj , content ) )
191253}
192254
255+ /**
256+ * Holds if `loadContent` is loaded from `nodeFrom` and written to `storeContent` of `nodeTo`.
257+ */
258+ private predicate flowsToLoadStoreStep (
259+ Node nodeFrom , TypeTrackingNode nodeTo , TypeTrackerContent loadContent ,
260+ TypeTrackerContent storeContent
261+ ) {
262+ exists ( Node obj |
263+ nodeTo .flowsTo ( obj ) and basicLoadStoreStep ( nodeFrom , obj , loadContent , storeContent )
264+ )
265+ }
266+
193267/**
194268 * INTERNAL: Use `TypeTracker` or `TypeBackTracker` instead.
195269 *
@@ -208,6 +282,11 @@ class StepSummary extends TStepSummary {
208282 or
209283 exists ( TypeTrackerContent content | this = LoadStep ( content ) | result = "load " + content )
210284 or
285+ exists ( TypeTrackerContent load , TypeTrackerContent store |
286+ this = LoadStoreStep ( load , store ) and
287+ result = "load-store " + load + " -> " + store
288+ )
289+ or
211290 this instanceof JumpStep and result = "jump"
212291 }
213292}
0 commit comments