Commit cd9d2b2a authored by Stefan Behnel's avatar Stefan Behnel

fix bug 633: make sure we own references to Python arguments passed into C functions

parent e3c9a786
...@@ -2953,7 +2953,14 @@ class SimpleCallNode(CallNode): ...@@ -2953,7 +2953,14 @@ class SimpleCallNode(CallNode):
# Coerce arguments # Coerce arguments
for i in range(min(max_nargs, actual_nargs)): for i in range(min(max_nargs, actual_nargs)):
formal_type = func_type.args[i].type formal_type = func_type.args[i].type
self.args[i] = self.args[i].coerce_to(formal_type, env) arg = self.args[i].coerce_to(formal_type, env)
if arg.is_attribute or not arg.is_simple:
# we do not own the argument's reference, but we must
# make sure it cannot be collected before we return
# from the function, so we create an owned temp
# reference to it
arg = arg.coerce_to_temp(env)
self.args[i] = arg
for i in range(max_nargs, actual_nargs): for i in range(max_nargs, actual_nargs):
if self.args[i].type.is_pyobject: if self.args[i].type.is_pyobject:
error(self.args[i].pos, error(self.args[i].pos,
......
cdef class Owner:
cdef object x
cdef call_me_with_owner(Owner owner, x):
owner.x = "def" # overwrite external reference
return x # crashes if x is not owned by function or caller
def test_ext_type_attr():
"""
>>> test_ext_type_attr()
'abc5'
"""
owner = Owner()
owner.x = ''.join("abc%d" % 5) # non-interned object
return call_me_with_owner(owner, owner.x)
cdef call_me_with_list(list l, x):
l[:] = [(1,2), (3,4)] # overwrite external reference
return x # crashes if x is not owned by function or caller
def test_index():
"""
>>> test_index()
[3, 4]
"""
l = [[1,2],[3,4]]
return call_me_with_list(l, l[1])
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment