@@ -40,6 +40,16 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
4040 */
4141 predicate isSink ( Node sink ) ;
4242
43+ /**
44+ * Holds if `sink` is a relevant data flow sink accepting `state`.
45+ */
46+ predicate isSinkReverse ( Node sink , FlowState state ) ;
47+
48+ /**
49+ * Holds if `sink` is a relevant data flow sink for any state.
50+ */
51+ predicate isSinkReverse ( Node sink ) ;
52+
4353 /**
4454 * Holds if data flow through `node` is prohibited. This completely removes
4555 * `node` from the data flow graph.
@@ -149,6 +159,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
149159
150160 predicate isSink ( Node sink , FlowState state ) { Config:: isSink ( sink ) and exists ( state ) }
151161
162+ predicate isSinkReverse ( Node sink , FlowState state ) {
163+ Config:: isSinkReverse ( sink ) and exists ( state )
164+ }
165+
152166 predicate isBarrier ( Node node , FlowState state ) { none ( ) }
153167
154168 predicate isBarrierIn ( Node node , FlowState state ) { none ( ) }
@@ -192,18 +206,32 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
192206 else any ( )
193207 }
194208
209+ pragma [ nomagic]
210+ private predicate isFilteredSinkReverse ( Node sink ) {
211+ (
212+ Config:: isSinkReverse ( sink , _) or
213+ Config:: isSinkReverse ( sink )
214+ ) and
215+ if Config:: observeDiffInformedIncrementalMode ( )
216+ then AlertFiltering:: filterByLocation ( sink .getLocation ( ) )
217+ else any ( )
218+ }
219+
195220 private predicate hasFilteredSource ( ) { isFilteredSource ( _) }
196221
197222 private predicate hasFilteredSink ( ) { isFilteredSink ( _) }
198223
224+ private predicate hasFilteredSinkReverse ( ) { isFilteredSinkReverse ( _) }
225+
199226 predicate isRelevantSource ( Node source , FlowState state ) {
200227 // If there are filtered sinks, we need to pass through all sources to preserve all alerts
201228 // with filtered sinks. Otherwise the only alerts of interest are those with filtered
202229 // sources, so we can perform the source filtering right here.
203230 Config:: isSource ( source , state ) and
204231 (
205232 isFilteredSource ( source ) or
206- hasFilteredSink ( )
233+ hasFilteredSink ( ) or
234+ hasFilteredSinkReverse ( )
207235 )
208236 }
209237
@@ -218,6 +246,17 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
218246 )
219247 }
220248
249+ predicate isRelevantSinkReverse ( Node sink , FlowState state ) {
250+ // If there are filtered sources, we need to pass through all sinks to preserve all alerts
251+ // with filtered sources. Otherwise the only alerts of interest are those with filtered
252+ // sinks, so we can perform the sink filtering right here.
253+ Config:: isSinkReverse ( sink , state ) and
254+ (
255+ isFilteredSinkReverse ( sink ) or
256+ hasFilteredSource ( )
257+ )
258+ }
259+
221260 predicate isRelevantSink ( Node sink ) {
222261 // If there are filtered sources, we need to pass through all sinks to preserve all alerts
223262 // with filtered sources. Otherwise the only alerts of interest are those with filtered
@@ -229,12 +268,30 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
229268 )
230269 }
231270
271+ predicate isRelevantSinkReverse ( Node sink ) {
272+ // If there are filtered sources, we need to pass through all sinks to preserve all alerts
273+ // with filtered sources. Otherwise the only alerts of interest are those with filtered
274+ // sinks, so we can perform the sink filtering right here.
275+ Config:: isSinkReverse ( sink ) and
276+ (
277+ isFilteredSinkReverse ( sink ) or
278+ hasFilteredSource ( )
279+ )
280+ }
281+
232282 bindingset [ source, sink]
233283 pragma [ inline_late]
234284 predicate isRelevantSourceSinkPair ( Node source , Node sink ) {
235285 isFilteredSource ( source ) or
236286 isFilteredSink ( sink )
237287 }
288+
289+ bindingset [ source, sink]
290+ pragma [ inline_late]
291+ predicate isRelevantSourceSinkPairReverse ( Node source , Node sink ) {
292+ isFilteredSource ( source ) or
293+ isFilteredSinkReverse ( sink )
294+ }
238295 }
239296
240297 private import SourceSinkFiltering
@@ -258,19 +315,28 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
258315
259316 private predicate outBarrier ( NodeEx node ) {
260317 exists ( Node n |
261- [ node .asNodeOrImplicitRead ( ) , node . asNodeReverse ( _ ) ] = n and
318+ node .asNodeOrImplicitRead ( ) = n and
262319 Config:: isBarrierOut ( n )
263320 |
264321 isRelevantSink ( n , _)
265322 or
266323 isRelevantSink ( n )
267324 )
325+ or
326+ exists ( Node n |
327+ node .asNodeReverse ( _) = n and
328+ Config:: isBarrierOut ( n )
329+ |
330+ isRelevantSinkReverse ( n , _)
331+ or
332+ isRelevantSinkReverse ( n )
333+ )
268334 }
269335
270336 pragma [ nomagic]
271337 private predicate outBarrier ( NodeEx node , FlowState state ) {
272338 exists ( Node n |
273- [ node .asNodeOrImplicitRead ( ) , node . asNodeReverse ( _ ) ] = n and
339+ node .asNodeOrImplicitRead ( ) = n and
274340 Config:: isBarrierOut ( n , state )
275341 |
276342 isRelevantSink ( n , state )
@@ -321,6 +387,13 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
321387 not stateBarrier ( node , state )
322388 }
323389
390+ pragma [ nomagic]
391+ private predicate sinkNodeWithStateReverse ( NodeEx node , FlowState state ) {
392+ isRelevantSinkReverse ( node .asNodeReverse ( _) , state ) and
393+ not fullBarrier ( node ) and
394+ not stateBarrier ( node , state )
395+ }
396+
324397 /** Provides the relevant barriers for a step from `node1` to `node2`. */
325398 bindingset [ node1, node2]
326399 private predicate stepFilter ( NodeEx node1 , NodeEx node2 ) {
@@ -707,6 +780,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
707780 fwdFlow ( node ) and
708781 fwdFlowState ( state ) and
709782 sinkNodeWithState ( node , state )
783+ or
784+ fwdFlow ( pragma [ only_bind_into ] ( node ) ) and
785+ fwdFlowState ( state ) and
786+ isRelevantSinkReverse ( node .asNodeReverse ( _) )
787+ or
788+ fwdFlow ( node ) and
789+ fwdFlowState ( state ) and
790+ sinkNodeWithState ( node , state )
791+ or
792+ fwdFlow ( node ) and
793+ fwdFlowState ( state ) and
794+ sinkNodeWithStateReverse ( node , state )
710795 }
711796
712797 /**
@@ -1025,7 +1110,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
10251110
10261111 private predicate sinkModel ( NodeEx node , string model ) {
10271112 sinkNode ( node , _) and
1028- exists ( Node n | n = node .asNodeOrImplicitRead ( ) |
1113+ exists ( Node n | n = [ node .asNodeOrImplicitRead ( ) , node . asNodeReverse ( _ ) ] |
10291114 knownSinkModel ( n , model )
10301115 or
10311116 not knownSinkModel ( n , _) and model = ""
@@ -2995,6 +3080,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
29953080 ( isRelevantSink ( n ) or isRelevantSink ( n , _) ) and
29963081 result .asNode ( ) = n
29973082 )
3083+ or
3084+ exists ( Node n |
3085+ node .asNodeReverse ( _) = n and
3086+ ( isRelevantSinkReverse ( n ) or isRelevantSinkReverse ( n , _) ) and
3087+ result = node
3088+ )
29983089 }
29993090
30003091 override PathNodeImpl getASuccessorImpl ( string label ) {
@@ -3489,6 +3580,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
34893580 /** Gets the underlying `Node`. */
34903581 final Node getNode ( ) { super .getNodeEx ( ) .projectToNode ( ) = result }
34913582
3583+ /** Gets the underlying `Node`, but only when it represents a reverse-flow node. */
3584+ final Node getNodeReverse ( ) { super .getNodeEx ( ) .asNodeReverse ( _) = result }
3585+
34923586 /** Gets the parameter node through which data is returned, if any. */
34933587 final ParameterNode asParameterReturnNode ( ) {
34943588 result = super .getNodeEx ( ) .asNodeReverse ( _)
@@ -4838,7 +4932,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
48384932 private predicate interestingCallableSink ( DataFlowCallable c ) {
48394933 exists ( Node n | c = getNodeEnclosingCallable ( n ) |
48404934 isRelevantSink ( n , _) or
4841- isRelevantSink ( n )
4935+ isRelevantSink ( n ) or
4936+ isRelevantSinkReverse ( n , _) or
4937+ isRelevantSinkReverse ( n )
48424938 )
48434939 or
48444940 exists ( DataFlowCallable mid | interestingCallableSink ( mid ) and callableStep ( c , mid ) )
@@ -4874,7 +4970,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
48744970 ce1 = TCallable ( getNodeEnclosingCallable ( n ) )
48754971 |
48764972 isRelevantSink ( n , _) or
4877- isRelevantSink ( n )
4973+ isRelevantSink ( n ) or
4974+ isRelevantSinkReverse ( n , _) or
4975+ isRelevantSinkReverse ( n )
48784976 )
48794977 }
48804978
@@ -4942,6 +5040,11 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
49425040 relevantState ( state ) and
49435041 not fullBarrier ( node ) and
49445042 not stateBarrier ( node , state )
5043+ or
5044+ isRelevantSinkReverse ( node .asNodeReverse ( _) ) and
5045+ relevantState ( state ) and
5046+ not fullBarrier ( node ) and
5047+ not stateBarrier ( node , state )
49455048 }
49465049
49475050 private newtype TSummaryCtx1 =
0 commit comments