@@ -102,11 +102,7 @@ private predicate summarizedLocalStep(Node nodeFrom, Node nodeTo) {
102102}
103103
104104/** Holds if there is a level step from `nodeFrom` to `nodeTo`. */
105- predicate levelStep ( Node nodeFrom , Node nodeTo ) {
106- summarizedLocalStep ( nodeFrom , nodeTo )
107- or
108- TypeTrackingStep:: step ( nodeFrom , nodeTo )
109- }
105+ predicate levelStep ( Node nodeFrom , Node nodeTo ) { summarizedLocalStep ( nodeFrom , nodeTo ) }
110106
111107pragma [ noinline]
112108private predicate argumentPositionMatch (
@@ -221,8 +217,6 @@ predicate basicStoreStep(Node nodeFrom, Node nodeTo, DataFlow::ContentSet conten
221217 nodeFrom = evaluateSummaryComponentStackLocal ( callable , call , input ) and
222218 nodeTo = evaluateSummaryComponentStackLocal ( callable , call , output )
223219 )
224- or
225- TypeTrackingStep:: storeStep ( nodeFrom , nodeTo , contents )
226220}
227221
228222/**
@@ -265,8 +259,6 @@ predicate basicLoadStep(Node nodeFrom, Node nodeTo, DataFlow::ContentSet content
265259 nodeFrom = evaluateSummaryComponentStackLocal ( callable , call , input ) and
266260 nodeTo = evaluateSummaryComponentStackLocal ( callable , call , output )
267261 )
268- or
269- TypeTrackingStep:: loadStep ( nodeFrom , nodeTo , contents )
270262}
271263
272264/**
@@ -285,8 +277,6 @@ predicate basicLoadStoreStep(
285277 nodeFrom = evaluateSummaryComponentStackLocal ( callable , call , input ) and
286278 nodeTo = evaluateSummaryComponentStackLocal ( callable , call , output )
287279 )
288- or
289- TypeTrackingStep:: loadStoreStep ( nodeFrom , nodeTo , loadContent , storeContent )
290280}
291281
292282/**
@@ -303,8 +293,6 @@ predicate basicWithoutContentStep(Node nodeFrom, Node nodeTo, ContentFilter filt
303293 nodeFrom = evaluateSummaryComponentStackLocal ( callable , call , input ) and
304294 nodeTo = evaluateSummaryComponentStackLocal ( callable , call , output )
305295 )
306- or
307- TypeTrackingStep:: withoutContentStep ( nodeFrom , nodeTo , filter )
308296}
309297
310298/**
@@ -321,8 +309,6 @@ predicate basicWithContentStep(Node nodeFrom, Node nodeTo, ContentFilter filter)
321309 nodeFrom = evaluateSummaryComponentStackLocal ( callable , call , input ) and
322310 nodeTo = evaluateSummaryComponentStackLocal ( callable , call , output )
323311 )
324- or
325- TypeTrackingStep:: withContentStep ( nodeFrom , nodeTo , filter )
326312}
327313
328314/**
@@ -339,7 +325,6 @@ private predicate hasStoreSummary(
339325 SummarizedCallable callable , DataFlow:: ContentSet contents , SummaryComponentStack input ,
340326 SummaryComponentStack output
341327) {
342- not TypeTrackingStep:: suppressSummary ( callable ) and
343328 callable .propagatesFlow ( input , push ( SummaryComponent:: content ( contents ) , output ) , true ) and
344329 not isNonLocal ( input .head ( ) ) and
345330 not isNonLocal ( output .head ( ) )
@@ -350,7 +335,6 @@ private predicate hasLoadSummary(
350335 SummarizedCallable callable , DataFlow:: ContentSet contents , SummaryComponentStack input ,
351336 SummaryComponentStack output
352337) {
353- not TypeTrackingStep:: suppressSummary ( callable ) and
354338 callable .propagatesFlow ( push ( SummaryComponent:: content ( contents ) , input ) , output , true ) and
355339 not isNonLocal ( input .head ( ) ) and
356340 not isNonLocal ( output .head ( ) )
@@ -361,7 +345,6 @@ private predicate hasLoadStoreSummary(
361345 SummarizedCallable callable , DataFlow:: ContentSet loadContents ,
362346 DataFlow:: ContentSet storeContents , SummaryComponentStack input , SummaryComponentStack output
363347) {
364- not TypeTrackingStep:: suppressSummary ( callable ) and
365348 callable
366349 .propagatesFlow ( push ( SummaryComponent:: content ( loadContents ) , input ) ,
367350 push ( SummaryComponent:: content ( storeContents ) , output ) , true ) and
@@ -394,7 +377,6 @@ private predicate hasWithoutContentSummary(
394377 SummaryComponentStack output
395378) {
396379 exists ( DataFlow:: ContentSet content |
397- not TypeTrackingStep:: suppressSummary ( callable ) and
398380 callable .propagatesFlow ( push ( SummaryComponent:: withoutContent ( content ) , input ) , output , true ) and
399381 filter = getFilterFromWithoutContentStep ( content ) and
400382 not isNonLocal ( input .head ( ) ) and
@@ -404,12 +386,12 @@ private predicate hasWithoutContentSummary(
404386}
405387
406388/**
407- * Gets a content filter to use for a `WithoutContent [content]` step, or has no result if
408- * the step should be treated as ordinary flow .
389+ * Gets a content filter to use for a `WithContent [content]` step, or has no result if
390+ * the step cannot be handled by type-tracking .
409391 *
410- * `WithoutContent ` is often used to perform strong updates on individual collection elements, but for
411- * type-tracking this is rarely beneficial and quite expensive. However, `WithoutContent` can be quite useful
412- * for restricting the type of an object, and in these cases we translate it to a filter.
392+ * `WithContent ` is often used to perform strong updates on individual collection elements (or rather
393+ * to preserve those that didn't get updated). But for type-tracking this is rarely beneficial and quite expensive.
394+ * However, `WithContent` can be quite useful for restricting the type of an object, and in these cases we translate it to a filter.
413395 */
414396private ContentFilter getFilterFromWithContentStep ( DataFlow:: ContentSet content ) {
415397 (
@@ -430,7 +412,6 @@ private predicate hasWithContentSummary(
430412 SummaryComponentStack output
431413) {
432414 exists ( DataFlow:: ContentSet content |
433- not TypeTrackingStep:: suppressSummary ( callable ) and
434415 callable .propagatesFlow ( push ( SummaryComponent:: withContent ( content ) , input ) , output , true ) and
435416 filter = getFilterFromWithContentStep ( content ) and
436417 not isNonLocal ( input .head ( ) ) and
@@ -475,7 +456,6 @@ private predicate dependsOnSummaryComponentStack(
475456 SummarizedCallable callable , SummaryComponentStack stack
476457) {
477458 exists ( callable .getACallSimple ( ) ) and
478- not TypeTrackingStep:: suppressSummary ( callable ) and
479459 (
480460 callable .propagatesFlow ( stack , _, true )
481461 or
@@ -544,116 +524,3 @@ private DataFlow::Node evaluateSummaryComponentStackLocal(
544524 )
545525 )
546526}
547-
548- private newtype TUnit = MkUnit ( )
549-
550- /**
551- * A data flow edge that should be followed by type tracking.
552- *
553- * This type of edge does not affect the local data flow graph, and is not used by data-flow configurations.
554- *
555- * Note: For performance reasons, all subclasses of this class should be part
556- * of the standard library, and their implementations may not depend on API graphs.
557- * For query-specific steps, consider including the custom steps in the type-tracking predicate itself.
558- */
559- class TypeTrackingStep extends TUnit {
560- /** Gets the string `"unit"`. */
561- string toString ( ) { result = "unit" }
562-
563- /**
564- * Holds if type-tracking should not attempt to derive steps from (simple) calls to `callable`.
565- *
566- * This can be done to manually control how steps are generated from such calls.
567- */
568- predicate suppressSummary ( SummarizedCallable callable ) { none ( ) }
569-
570- /**
571- * Holds if type-tracking should step from `pred` to `succ`.
572- */
573- predicate step ( Node pred , Node succ ) { none ( ) }
574-
575- /**
576- * Holds if type-tracking should step from `pred` into the `content` of `succ`.
577- */
578- predicate storeStep ( Node pred , TypeTrackingNode succ , TypeTrackerContent content ) { none ( ) }
579-
580- /**
581- * Holds if type-tracking should step from the `content` of `pred` to `succ`.
582- */
583- predicate loadStep ( Node pred , Node succ , TypeTrackerContent content ) { none ( ) }
584-
585- /**
586- * Holds if type-tracking should step from the `loadContent` of `pred` to the `storeContent` in `succ`.
587- */
588- predicate loadStoreStep (
589- Node pred , TypeTrackingNode succ , TypeTrackerContent loadContent ,
590- TypeTrackerContent storeContent
591- ) {
592- none ( )
593- }
594-
595- /**
596- * Holds if type-tracking should step from `pred` to `succ` but block flow of contents matched by `filter` through here.
597- */
598- predicate withoutContentStep ( Node pred , Node succ , ContentFilter filter ) { none ( ) }
599-
600- /**
601- * Holds if type-tracking should step from `pred` to `succ` if inside a content matched by `filter`.
602- */
603- predicate withContentStep ( Node pred , Node succ , ContentFilter filter ) { none ( ) }
604- }
605-
606- /** Provides access to the steps contributed by subclasses of `SharedTypeTrackingStep`. */
607- module TypeTrackingStep {
608- /**
609- * Holds if type-tracking should not attempt to derive steps from (simple) calls to `callable`.
610- *
611- * This can be done to manually control how steps are generated from such calls.
612- */
613- predicate suppressSummary ( SummarizedCallable callable ) {
614- any ( TypeTrackingStep st ) .suppressSummary ( callable )
615- }
616-
617- /**
618- * Holds if type-tracking should step from `pred` to `succ`.
619- */
620- predicate step ( Node pred , Node succ ) { any ( TypeTrackingStep st ) .step ( pred , succ ) }
621-
622- /**
623- * Holds if type-tracking should step from `pred` into the `content` of `succ`.
624- */
625- predicate storeStep ( Node pred , TypeTrackingNode succ , TypeTrackerContent content ) {
626- any ( TypeTrackingStep st ) .storeStep ( pred , succ , content )
627- }
628-
629- /**
630- * Holds if type-tracking should step from the `content` of `pred` to `succ`.
631- */
632- predicate loadStep ( Node pred , Node succ , TypeTrackerContent content ) {
633- any ( TypeTrackingStep st ) .loadStep ( pred , succ , content )
634- }
635-
636- /**
637- * Holds if type-tracking should step from the `loadContent` of `pred` to the `storeContent` in `succ`.
638- */
639- predicate loadStoreStep (
640- Node pred , TypeTrackingNode succ , TypeTrackerContent loadContent ,
641- TypeTrackerContent storeContent
642- ) {
643- any ( TypeTrackingStep st ) .loadStoreStep ( pred , succ , loadContent , storeContent )
644- }
645-
646- /**
647- * Holds if type-tracking should step from `pred` to `succ` but block flow of contents matched by `filter` through here.
648- */
649- predicate withoutContentStep ( Node pred , Node succ , ContentFilter filter ) {
650- any ( TypeTrackingStep st ) .withoutContentStep ( pred , succ , filter )
651- }
652-
653- /**
654- * Holds if type-tracking should step from `pred` to `succ` if inside a content matched by `filter`.
655- */
656- predicate withContentStep ( Node pred , Node succ , ContentFilter filter ) {
657- any ( TypeTrackingStep st ) .withContentStep ( pred , succ , filter )
658- }
659- }
0 commit comments