Fix refcount bug with buffers of objects
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Thu, 27 Nov 2008 12:37:37 +0000 (13:37 +0100)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Thu, 27 Nov 2008 12:37:37 +0000 (13:37 +0100)
May have been introduced by the result_code refactor.

Cython/Compiler/ExprNodes.py
tests/run/bufaccess.pyx

index d7190b909d6a886d7b5a69c964f34513ef87ac01..bcd4b3e71d5a0fcbd22ceb243b7d84e2aac829bd 100644 (file)
@@ -1719,17 +1719,12 @@ class IndexNode(ExprNode):
             # Must manage refcounts. Decref what is already there
             # and incref what we put in.
             ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False)
-            if rhs.is_temp:
-                rhs_code = code.funcstate.allocate_temp(rhs.type, manage_ref=False)
-            else:
-                rhs_code = rhs.result()
+            rhs_code = rhs.result()
             code.putln("%s = %s;" % (ptr, ptrexpr))
             code.putln("Py_DECREF(*%s); Py_INCREF(%s);" % (
                 ptr, rhs_code
                 ))
             code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
-            if rhs.is_temp:
-                code.funcstate.release_temp(rhs_code)
             code.funcstate.release_temp(ptr)
         else: 
             # Simple case
index ce228cf4c805be736425b03eeb73a71a5278d9c6..d9f814f2608665a7b53d9ed106415ba45501ad59 100644 (file)
@@ -972,6 +972,33 @@ def assign_to_object(object[object] buf, int idx, obj):
     """
     buf[idx] = obj
     
+@testcase
+def assign_temporary_to_object(object[object] buf):
+    """
+    See comments on printbuf_object above.
+
+    >>> a, b = [1, 2, 3], {4:23}
+    >>> get_refcount(a)
+    2
+    >>> addref(a)
+    >>> A = ObjectMockBuffer(None, [b, a])
+    >>> get_refcount(a)
+    3
+    >>> assign_temporary_to_object(A)
+    >>> get_refcount(a)
+    2
+    
+    >>> printbuf_object(A, (2,))
+    {4: 23} 2
+    {1: 8} 2
+
+    To avoid leaking a reference in our testcase we need to
+    replace the temporary with something we can manually decref :-)
+    >>> assign_to_object(A, 1, a)
+    >>> decref(a)
+    """
+    buf[1] = {3-2: 2+(2*4)-2}
+
 #
 # cast option
 #