@@ -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 = ""
@@ -3021,6 +3106,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
30213106 ( isRelevantSink ( n ) or isRelevantSink ( n , _) ) and
30223107 result .asNode ( ) = n
30233108 )
3109+ or
3110+ exists ( Node n |
3111+ node .asNodeReverse ( _) = n and
3112+ ( isRelevantSinkReverse ( n ) or isRelevantSinkReverse ( n , _) ) and
3113+ result = node
3114+ )
30243115 }
30253116
30263117 override PathNodeImpl getASuccessorImpl ( string label ) {
@@ -3520,6 +3611,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
35203611 /** Gets the underlying `Node`. */
35213612 final Node getNode ( ) { super .getNodeEx ( ) .projectToNode ( ) = result }
35223613
3614+ /** Gets the underlying `Node`, but only when it represents a reverse-flow node. */
3615+ final Node getNodeReverse ( ) { super .getNodeEx ( ) .asNodeReverse ( _) = result }
3616+
35233617 /** Gets the parameter node through which data is returned, if any. */
35243618 final ParameterNode asParameterReturnNode ( ) {
35253619 result = super .getNodeEx ( ) .asNodeReverse ( _)
@@ -4869,7 +4963,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
48694963 private predicate interestingCallableSink ( DataFlowCallable c ) {
48704964 exists ( Node n | c = getNodeEnclosingCallable ( n ) |
48714965 isRelevantSink ( n , _) or
4872- isRelevantSink ( n )
4966+ isRelevantSink ( n ) or
4967+ isRelevantSinkReverse ( n , _) or
4968+ isRelevantSinkReverse ( n )
48734969 )
48744970 or
48754971 exists ( DataFlowCallable mid | interestingCallableSink ( mid ) and callableStep ( c , mid ) )
@@ -4905,7 +5001,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
49055001 ce1 = TCallable ( getNodeEnclosingCallable ( n ) )
49065002 |
49075003 isRelevantSink ( n , _) or
4908- isRelevantSink ( n )
5004+ isRelevantSink ( n ) or
5005+ isRelevantSinkReverse ( n , _) or
5006+ isRelevantSinkReverse ( n )
49095007 )
49105008 }
49115009
@@ -4973,6 +5071,11 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
49735071 relevantState ( state ) and
49745072 not fullBarrier ( node ) and
49755073 not stateBarrier ( node , state )
5074+ or
5075+ isRelevantSinkReverse ( node .asNodeReverse ( _) ) and
5076+ relevantState ( state ) and
5077+ not fullBarrier ( node ) and
5078+ not stateBarrier ( node , state )
49765079 }
49775080
49785081 private newtype TSummaryCtx1 =
0 commit comments