@@ -101,7 +101,7 @@ private newtype TTypeTracker = MkTypeTracker(Boolean hasCall, OptionalPropertyNa
101101 * source/sink relation, that is, it may determine that a node has a given type,
102102 * but it won't determine where that type came from.
103103 *
104- * It is recommended that all uses of this type is written on the following form,
104+ * It is recommended that all uses of this type are written in the following form,
105105 * for tracking some type `myType`:
106106 * ```
107107 * DataFlow::SourceNode myType(DataFlow::TypeTracker t) {
@@ -116,8 +116,12 @@ private newtype TTypeTracker = MkTypeTracker(Boolean hasCall, OptionalPropertyNa
116116 * DataFlow::SourceNode myType() { result = myType(DataFlow::TypeTracker::end()) }
117117 * ```
118118 *
119- * To track values backwards, which can be useful for tracking
120- * the type of a callback, use the `TypeBackTracker` class instead.
119+ * Instead of `result = myType(t2).track(t2, t)`, you can also use the equivalent
120+ * `t = t2.step(myType(t2), result)`. If you additionally want to track individual
121+ * intra-procedural steps, use `t = t2.smallstep(myCallback(t2), result)`.
122+ *
123+ * To track values backwards, which can be useful for tracking the type of a callback,
124+ * use the `TypeBackTracker` class instead.
121125 */
122126class TypeTracker extends TTypeTracker {
123127 Boolean hasCall ;
@@ -172,6 +176,37 @@ class TypeTracker extends TTypeTracker {
172176 * This predicate is only defined if the type has not been tracked into a property.
173177 */
174178 TypeTracker continue ( ) { prop = "" and result = this }
179+
180+ /**
181+ * Gets the summary that corresponds to having taken a forwards
182+ * heap and/or inter-procedural step from `pred` to `succ`.
183+ */
184+ pragma [ inline]
185+ TypeTracker step ( DataFlow:: SourceNode pred , DataFlow:: SourceNode succ ) {
186+ exists ( StepSummary summary |
187+ StepSummary:: step ( pred , succ , summary ) and
188+ result = this .append ( summary )
189+ )
190+ }
191+
192+ /**
193+ * Gets the summary that corresponds to having taken a forwards
194+ * local, heap and/or inter-procedural step from `pred` to `succ`.
195+ *
196+ * Unlike `TypeTracker::step`, this predicate exposes all edges
197+ * in the flow graph, and not just the edges between `SourceNode`s.
198+ * It may therefore be less performant.
199+ */
200+ pragma [ inline]
201+ TypeTracker smallstep ( DataFlow:: Node pred , DataFlow:: Node succ ) {
202+ exists ( StepSummary summary |
203+ StepSummary:: smallstep ( pred , succ , summary ) and
204+ result = this .append ( summary )
205+ )
206+ or
207+ succ = pred .getASuccessor ( ) and
208+ result = this
209+ }
175210}
176211
177212module TypeTracker {
@@ -192,20 +227,25 @@ private newtype TTypeBackTracker = MkTypeBackTracker(Boolean hasReturn, Optional
192227 * it may determine that a node will be used in an API call somewhere, but it won't
193228 * determine exactly where that use was, or the path that led to the use.
194229 *
195- * It is recommended that all uses of this type is written on the following form,
230+ * It is recommended that all uses of this type are written in the following form,
196231 * for back-tracking some callback type `myCallback`:
232+ *
197233 * ```
198234 * DataFlow::SourceNode myCallback(DataFlow::TypeBackTracker t) {
199235 * t.start() and
200236 * result = (< some API call >).getArgument(< n >).getALocalSource()
201237 * or
202238 * exists (DataFlow::TypeBackTracker t2 |
203- * t2 = t.step(result, myCallback(t2))
239+ * result = myCallback(t2).backtrack(t2, t )
204240 * )
205241 * }
206242 *
207243 * DataFlow::SourceNode myCallback() { result = myCallback(DataFlow::TypeBackTracker::end()) }
208244 * ```
245+ *
246+ * Instead of `result = myCallback(t2).backtrack(t2, t)`, you can also use the equivalent
247+ * `t2 = t.step(result, myCallback(t2))`. If you additionally want to track individual
248+ * intra-procedural steps, use `t2 = t.smallstep(result, myCallback(t2))`.
209249 */
210250class TypeBackTracker extends TTypeBackTracker {
211251 Boolean hasReturn ;
0 commit comments