@@ -39,33 +39,55 @@ def setFoo(self, foo):
3939 self .foo = foo
4040
4141def setFoo (obj , x ):
42- SINK_F (obj .foo )
4342 obj .foo = x
4443
45- @expects (2 ) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
44+
45+ @expects (3 ) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
4646def test_indirect_assign ():
47- myobj = MyObj ("OK" )
47+ myobj = MyObj (NONSOURCE )
48+ SINK_F (myobj .foo )
4849
4950 setFoo (myobj , SOURCE )
5051 SINK (myobj .foo ) # $ flow="SOURCE, l:-1 -> myobj.foo"
5152
53+ setFoo (myobj , NONSOURCE )
54+ SINK_F (myobj .foo ) # $ SPURIOUS: flow="SOURCE, l:-4 -> myobj.foo"
5255
56+
57+ @expects (3 ) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
5358def test_indirect_assign_method ():
54- myobj = MyObj ("OK" )
59+ myobj = MyObj (NONSOURCE )
60+ SINK_F (myobj .foo )
5561
5662 myobj .setFoo (SOURCE )
5763 SINK (myobj .foo ) # $ flow="SOURCE, l:-1 -> myobj.foo"
5864
65+ myobj .setFoo (NONSOURCE )
66+ SINK_F (myobj .foo ) # $ SPURIOUS: flow="SOURCE, l:-4 -> myobj.foo"
5967
60- def test_direct_assign ():
68+
69+ @expects (3 ) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
70+ def test_indirect_assign_bound_method ():
6171 myobj = MyObj (NONSOURCE )
62- myobj .foo = SOURCE
63- SINK (myobj .foo ) # $ flow="SOURCE, l:-1 -> myobj.foo"
72+ SINK_F (myobj .foo )
73+
74+ sf = myobj .setFoo
6475
76+ sf (SOURCE )
77+ SINK (myobj .foo ) # $ MISSING: flow="SOURCE, l:-1 -> myobj.foo"
6578
66- def test_direct_assign_overwrite ():
79+ sf (NONSOURCE )
80+ SINK_F (myobj .foo )
81+
82+
83+ @expects (3 ) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
84+ def test_direct_assign ():
6785 myobj = MyObj (NONSOURCE )
86+ SINK_F (myobj .foo )
87+
6888 myobj .foo = SOURCE
89+ SINK (myobj .foo ) # $ flow="SOURCE, l:-1 -> myobj.foo"
90+
6991 myobj .foo = NONSOURCE
7092 SINK_F (myobj .foo )
7193
@@ -160,40 +182,6 @@ def test_nested_obj_method():
160182 a .getObj ().foo = x
161183 SINK (a .obj .foo ) # $ flow="SOURCE, l:-3 -> a.obj.foo"
162184
163- # ------------------------------------------------------------------------------
164- # Bound Method calls
165- # ------------------------------------------------------------------------------
166-
167- class Foo :
168- def __init__ (self , x ):
169- self .x = x
170-
171- def update_x (self , x ):
172- self .x = x
173-
174- @expects (7 ) # $ unresolved_call=expects(..) unresolved_call=expects(..)(..)
175- def test_bound_method_call ():
176- # direct assignment
177- foo = Foo (None )
178- SINK_F (foo .x )
179- foo .x = SOURCE
180- SINK (foo .x ) # $ flow="SOURCE, l:-1 -> foo.x"
181- foo .x = None
182- SINK_F (foo .x )
183-
184- # assignment through function
185- foo = Foo (SOURCE )
186- SINK (foo .x ) # $ flow="SOURCE, l:-1 -> foo.x"
187- foo .update_x (None )
188- SINK_F (foo .x ) # $ flow="SOURCE, l:-3 -> foo.x"
189-
190- # assignment through bound-method calls
191- foo = Foo (SOURCE )
192- ux = foo .update_x
193- SINK (foo .x ) # $ flow="SOURCE, l:-2 -> foo.x"
194- ux (None )
195- SINK_F (foo .x ) # $ SPURIOUS: flow="SOURCE, l:-4 -> foo.x"
196-
197185
198186# ------------------------------------------------------------------------------
199187# Crosstalk test -- using different function based on conditional
0 commit comments