@@ -20,7 +20,8 @@ module ProductFlow {
2020 * `source1` and `source2` must belong to the same callable.
2121 */
2222 predicate isSourcePair (
23- DataFlow:: Node source1 , string state1 , DataFlow:: Node source2 , string state2
23+ DataFlow:: Node source1 , DataFlow:: FlowState state1 , DataFlow:: Node source2 ,
24+ DataFlow:: FlowState state2
2425 ) {
2526 state1 = "" and
2627 state2 = "" and
@@ -89,6 +90,61 @@ module ProductFlow {
8990 */
9091 predicate isBarrierOut2 ( DataFlow:: Node node ) { none ( ) }
9192
93+ /*
94+ * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps in
95+ * the first projection of the product dataflow graph.
96+ */
97+
98+ predicate isAdditionalFlowStep1 ( DataFlow:: Node node1 , DataFlow:: Node node2 ) { none ( ) }
99+
100+ /**
101+ * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps in
102+ * the first projection of the product dataflow graph.
103+ *
104+ * This step is only applicable in `state1` and updates the flow state to `state2`.
105+ */
106+ predicate isAdditionalFlowStep1 (
107+ DataFlow:: Node node1 , DataFlow:: FlowState state1 , DataFlow:: Node node2 ,
108+ DataFlow:: FlowState state2
109+ ) {
110+ state1 instanceof DataFlow:: FlowStateEmpty and
111+ state2 instanceof DataFlow:: FlowStateEmpty and
112+ this .isAdditionalFlowStep1 ( node1 , node2 )
113+ }
114+
115+ /**
116+ * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps in
117+ * the second projection of the product dataflow graph.
118+ */
119+ predicate isAdditionalFlowStep2 ( DataFlow:: Node node1 , DataFlow:: Node node2 ) { none ( ) }
120+
121+ /**
122+ * Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps in
123+ * the second projection of the product dataflow graph.
124+ *
125+ * This step is only applicable in `state1` and updates the flow state to `state2`.
126+ */
127+ predicate isAdditionalFlowStep2 (
128+ DataFlow:: Node node1 , DataFlow:: FlowState state1 , DataFlow:: Node node2 ,
129+ DataFlow:: FlowState state2
130+ ) {
131+ state1 instanceof DataFlow:: FlowStateEmpty and
132+ state2 instanceof DataFlow:: FlowStateEmpty and
133+ this .isAdditionalFlowStep2 ( node1 , node2 )
134+ }
135+
136+ /**
137+ * Holds if data flow into `node` is prohibited in the first projection of the product
138+ * dataflow graph.
139+ */
140+ predicate isBarrierIn1 ( DataFlow:: Node node ) { none ( ) }
141+
142+ /**
143+ * Holds if data flow into `node` is prohibited in the second projection of the product
144+ * dataflow graph.
145+ */
146+ predicate isBarrierIn2 ( DataFlow:: Node node ) { none ( ) }
147+
92148 predicate hasFlowPath (
93149 DataFlow:: PathNode source1 , DataFlow2:: PathNode source2 , DataFlow:: PathNode sink1 ,
94150 DataFlow2:: PathNode sink2
@@ -103,54 +159,78 @@ module ProductFlow {
103159 class Conf1 extends DataFlow:: Configuration {
104160 Conf1 ( ) { this = "Conf1" }
105161
106- override predicate isSource ( DataFlow:: Node source , string state ) {
162+ override predicate isSource ( DataFlow:: Node source , DataFlow :: FlowState state ) {
107163 exists ( Configuration conf | conf .isSourcePair ( source , state , _, _) )
108164 }
109165
110- override predicate isSink ( DataFlow:: Node sink , string state ) {
166+ override predicate isSink ( DataFlow:: Node sink , DataFlow :: FlowState state ) {
111167 exists ( Configuration conf | conf .isSinkPair ( sink , state , _, _) )
112168 }
113169
114- override predicate isBarrier ( DataFlow:: Node node , string state ) {
170+ override predicate isBarrier ( DataFlow:: Node node , DataFlow :: FlowState state ) {
115171 exists ( Configuration conf | conf .isBarrier1 ( node , state ) )
116172 }
117173
118174 override predicate isBarrierOut ( DataFlow:: Node node ) {
119175 exists ( Configuration conf | conf .isBarrierOut1 ( node ) )
120176 }
177+
178+ override predicate isAdditionalFlowStep (
179+ DataFlow:: Node node1 , DataFlow:: FlowState state1 , DataFlow:: Node node2 ,
180+ DataFlow:: FlowState state2
181+ ) {
182+ exists ( Configuration conf | conf .isAdditionalFlowStep1 ( node1 , state1 , node2 , state2 ) )
183+ }
184+
185+ override predicate isBarrierIn ( DataFlow:: Node node ) {
186+ exists ( Configuration conf | conf .isBarrierIn1 ( node ) )
187+ }
121188 }
122189
123190 class Conf2 extends DataFlow2:: Configuration {
124191 Conf2 ( ) { this = "Conf2" }
125192
126- override predicate isSource ( DataFlow:: Node source , string state ) {
127- exists ( Configuration conf , DataFlow:: Node source1 |
128- conf .isSourcePair ( source1 , _ , source , state ) and
129- any ( Conf1 c ) .hasFlow ( source1 , _)
193+ override predicate isSource ( DataFlow:: Node source , DataFlow :: FlowState state ) {
194+ exists ( Configuration conf , DataFlow:: PathNode source1 |
195+ conf .isSourcePair ( source1 . getNode ( ) , source1 . getState ( ) , source , state ) and
196+ any ( Conf1 c ) .hasFlowPath ( source1 , _)
130197 )
131198 }
132199
133- override predicate isSink ( DataFlow:: Node sink , string state ) {
134- exists ( Configuration conf , DataFlow:: Node sink1 |
135- conf .isSinkPair ( sink1 , _, sink , state ) and any ( Conf1 c ) .hasFlow ( _, sink1 )
200+ override predicate isSink ( DataFlow:: Node sink , DataFlow:: FlowState state ) {
201+ exists ( Configuration conf , DataFlow:: PathNode sink1 |
202+ conf .isSinkPair ( sink1 .getNode ( ) , sink1 .getState ( ) , sink , state ) and
203+ any ( Conf1 c ) .hasFlowPath ( _, sink1 )
136204 )
137205 }
138206
139- override predicate isBarrier ( DataFlow:: Node node , string state ) {
207+ override predicate isBarrier ( DataFlow:: Node node , DataFlow :: FlowState state ) {
140208 exists ( Configuration conf | conf .isBarrier2 ( node , state ) )
141209 }
142210
143211 override predicate isBarrierOut ( DataFlow:: Node node ) {
144212 exists ( Configuration conf | conf .isBarrierOut2 ( node ) )
145213 }
214+
215+ override predicate isAdditionalFlowStep (
216+ DataFlow:: Node node1 , DataFlow:: FlowState state1 , DataFlow:: Node node2 ,
217+ DataFlow:: FlowState state2
218+ ) {
219+ exists ( Configuration conf | conf .isAdditionalFlowStep2 ( node1 , state1 , node2 , state2 ) )
220+ }
221+
222+ override predicate isBarrierIn ( DataFlow:: Node node ) {
223+ exists ( Configuration conf | conf .isBarrierIn2 ( node ) )
224+ }
146225 }
147226 }
148227
228+ pragma [ nomagic]
149229 private predicate reachableInterprocEntry (
150230 Configuration conf , DataFlow:: PathNode source1 , DataFlow2:: PathNode source2 ,
151231 DataFlow:: PathNode node1 , DataFlow2:: PathNode node2
152232 ) {
153- conf .isSourcePair ( node1 .getNode ( ) , _ , node2 .getNode ( ) , _ ) and
233+ conf .isSourcePair ( node1 .getNode ( ) , node1 . getState ( ) , node2 .getNode ( ) , node2 . getState ( ) ) and
154234 node1 = source1 and
155235 node2 = source2
156236 or
@@ -213,7 +293,7 @@ module ProductFlow {
213293 ) {
214294 exists ( DataFlow:: PathNode mid1 , DataFlow2:: PathNode mid2 |
215295 reachableInterprocEntry ( conf , source1 , source2 , mid1 , mid2 ) and
216- conf .isSinkPair ( sink1 .getNode ( ) , _ , sink2 .getNode ( ) , _ ) and
296+ conf .isSinkPair ( sink1 .getNode ( ) , sink1 . getState ( ) , sink2 .getNode ( ) , sink2 . getState ( ) ) and
217297 localPathStep1 * ( mid1 , sink1 ) and
218298 localPathStep2 * ( mid2 , sink2 )
219299 )
0 commit comments