@@ -194,6 +194,128 @@ def test_bound_method_call():
194194 ux (None )
195195 SINK_F (foo .x ) # $ SPURIOUS: flow="SOURCE, l:-4 -> foo.x"
196196
197+
198+ # ------------------------------------------------------------------------------
199+ # Crosstalk test -- using different function based on conditional
200+ # ------------------------------------------------------------------------------
201+
202+ class CrosstalkTestX :
203+ def __init__ (self ):
204+ self .x = None
205+ self .y = None
206+
207+ def setx (self , value ):
208+ self .x = value
209+
210+ def setvalue (self , value ):
211+ self .x = value
212+
213+
214+ class CrosstalkTestY :
215+ def __init__ (self ):
216+ self .x = None
217+ self .y = None
218+
219+ def sety (self ,value ):
220+ self .y = value
221+
222+ def setvalue (self , value ):
223+ self .y = value
224+
225+
226+ @expects (8 ) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
227+ def test_no_crosstalk_reference (cond = True ):
228+ objx = CrosstalkTestX ()
229+ SINK_F (objx .x )
230+ SINK_F (objx .y )
231+
232+ objy = CrosstalkTestY ()
233+ SINK_F (objy .x )
234+ SINK_F (objy .y )
235+
236+ if cond :
237+ objx .setvalue (SOURCE )
238+ else :
239+ objy .setvalue (SOURCE )
240+
241+ SINK (objx .x ) # $ flow="SOURCE, l:-4 -> objx.x"
242+ SINK_F (objx .y )
243+ SINK_F (objy .x )
244+ SINK_F (objy .y ) # $ flow="SOURCE, l:-5 -> objy.y"
245+
246+
247+ @expects (8 ) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
248+ def test_potential_crosstalk_different_name (cond = True ):
249+ objx = CrosstalkTestX ()
250+ SINK_F (objx .x )
251+ SINK_F (objx .y )
252+
253+ objy = CrosstalkTestY ()
254+ SINK_F (objy .x )
255+ SINK_F (objy .y )
256+
257+ if cond :
258+ func = objx .setx
259+ else :
260+ func = objy .sety
261+
262+ func (SOURCE )
263+
264+ SINK (objx .x ) # $ MISSING: flow="SOURCE, l:-2 -> objx.x"
265+ SINK_F (objx .y )
266+ SINK_F (objy .x )
267+ SINK_F (objy .y ) # $ MISSING: flow="SOURCE, l:-5 -> objy.y"
268+
269+
270+ @expects (8 ) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
271+ def test_potential_crosstalk_same_name (cond = True ):
272+ objx = CrosstalkTestX ()
273+ SINK_F (objx .x )
274+ SINK_F (objx .y )
275+
276+ objy = CrosstalkTestY ()
277+ SINK_F (objy .x )
278+ SINK_F (objy .y )
279+
280+ if cond :
281+ func = objx .setvalue
282+ else :
283+ func = objy .setvalue
284+
285+ func (SOURCE )
286+
287+ SINK (objx .x ) # $ MISSING: flow="SOURCE, l:-2 -> objx.x"
288+ SINK_F (objx .y )
289+ SINK_F (objy .x )
290+ SINK_F (objy .y ) # $ MISSING: flow="SOURCE, l:-5 -> objy.y"
291+
292+
293+ @expects (10 ) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
294+ def test_potential_crosstalk_same_name_object_reference (cond = True ):
295+ objx = CrosstalkTestX ()
296+ SINK_F (objx .x )
297+ SINK_F (objx .y )
298+
299+ objy = CrosstalkTestY ()
300+ SINK_F (objy .x )
301+ SINK_F (objy .y )
302+
303+ if cond :
304+ obj = objx
305+ else :
306+ obj = objy
307+
308+ obj .setvalue (SOURCE )
309+
310+ SINK (objx .x ) # $ MISSING: flow="SOURCE, l:-2 -> objx.x"
311+ SINK_F (objx .y )
312+ SINK_F (objy .x )
313+ SINK_F (objy .y ) # $ MISSING: flow="SOURCE, l:-5 -> objy.y"
314+
315+ SINK (obj .x ) # $ flow="SOURCE, l:-7 -> obj.x"
316+ SINK_F (obj .y ) # $ flow="SOURCE, l:-8 -> obj.y"
317+
318+
197319# ------------------------------------------------------------------------------
198320# Global scope
199321# ------------------------------------------------------------------------------
0 commit comments