@@ -40,6 +40,16 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang>{
4040 */
4141predicate 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
150160predicate 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+
152166predicate isBarrier ( Node node , FlowState state ) { none ( ) }
153167
154168predicate isBarrierIn ( Node node , FlowState state ) { none ( ) }
@@ -192,18 +206,32 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang>{
192206else 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+
195220private predicate hasFilteredSource ( ) { isFilteredSource ( _) }
196221
197222private predicate hasFilteredSink ( ) { isFilteredSink ( _) }
198223
224+ private predicate hasFilteredSinkReverse ( ) { isFilteredSinkReverse ( _) }
225+
199226predicate 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(
205232isFilteredSource ( 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+
221260predicate 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+
232282bindingset [ source, sink]
233283pragma [ inline_late]
234284predicate isRelevantSourceSinkPair ( Node source , Node sink ) {
235285isFilteredSource ( source ) or
236286isFilteredSink ( 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
240297private import SourceSinkFiltering
@@ -258,19 +315,28 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang>{
258315
259316private predicate outBarrier ( NodeEx node ) {
260317exists ( Node n |
261- [ node .asNodeOrImplicitRead ( ) , node . asNodeReverse ( _ ) ] = n and
318+ node .asNodeOrImplicitRead ( ) = n and
262319 Config:: isBarrierOut ( n )
263320|
264321isRelevantSink ( n , _)
265322or
266323isRelevantSink ( 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
270336pragma [ nomagic]
271337private predicate outBarrier ( NodeEx node , FlowState state ) {
272338exists ( Node n |
273- [ node .asNodeOrImplicitRead ( ) , node . asNodeReverse ( _ ) ] = n and
339+ node .asNodeOrImplicitRead ( ) = n and
274340 Config:: isBarrierOut ( n , state )
275341|
276342isRelevantSink ( n , state )
@@ -321,6 +387,13 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang>{
321387not 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`. */
325398bindingset [ node1, node2]
326399private predicate stepFilter ( NodeEx node1 , NodeEx node2 ) {
@@ -707,6 +780,18 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang>{
707780fwdFlow ( node ) and
708781fwdFlowState ( state ) and
709782sinkNodeWithState ( 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
10261111private predicate sinkModel ( NodeEx node , string model ) {
10271112sinkNode ( node , _) and
1028- exists ( Node n | n = node .asNodeOrImplicitRead ( ) |
1113+ exists ( Node n | n = [ node .asNodeOrImplicitRead ( ) , node . asNodeReverse ( _ ) ] |
10291114knownSinkModel ( n , model )
10301115or
10311116not knownSinkModel ( n , _) and model = ""
@@ -3021,6 +3106,12 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang>{
30213106( isRelevantSink ( n ) or isRelevantSink ( n , _) ) and
30223107result .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
30263117override PathNodeImpl getASuccessorImpl ( string label ) {
@@ -3520,6 +3611,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang>{
35203611/** Gets the underlying `Node`. */
35213612final 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. */
35243618final ParameterNode asParameterReturnNode ( ) {
35253619result = super .getNodeEx ( ) .asNodeReverse ( _)
@@ -4869,7 +4963,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang>{
48694963private predicate interestingCallableSink ( DataFlowCallable c ) {
48704964exists ( Node n | c = getNodeEnclosingCallable ( n ) |
48714965isRelevantSink ( n , _) or
4872- isRelevantSink ( n )
4966+ isRelevantSink ( n ) or
4967+ isRelevantSinkReverse ( n , _) or
4968+ isRelevantSinkReverse ( n )
48734969)
48744970or
48754971exists ( DataFlowCallable mid | interestingCallableSink ( mid ) and callableStep ( c , mid ) )
@@ -4905,7 +5001,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang>{
49055001ce1 = TCallable ( getNodeEnclosingCallable ( n ) )
49065002|
49075003isRelevantSink ( 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>{
49735071relevantState ( state ) and
49745072not fullBarrier ( node ) and
49755073not 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
49785081private newtype TSummaryCtx1 =
0 commit comments