As the web servers appears to be down at the moment, I'm posting it here for the moment.

This is the bug reported recently. It's related to a problem in allocate_temps of SequenceNode (basically two nodes could get the same temp), and has likely been there for a long time.

It hits some nested tuple unpacking cases depending on the number of variables in the nested vs. outer tuple.

The refnanny catches a segfault on trivial code like this:

def g():
    return ((3, 2), 1, 0)

def func2():
    (a, b), c, d = g()


Of course, the whole function which was buggy has disappeared in cython-unstable. So this is kind of depressing :-) But at least now 0.11.2 isn't blocked by having to merge -unstable.

--
Dag Sverre
# HG changeset patch
# User Dag Sverre Seljebotn <[email protected]>
# Date 1240685917 -7200
# Node ID 4179f49ac82d7ca5dafd17883ca1cfbccdc20c37
# Parent  c3bf82e34e54ef7ef0976ffa2ae68b4cfd738ffe
Fix tuple unpacking bug (related to old temps)

diff -r c3bf82e34e54 -r 4179f49ac82d Cython/Compiler/ExprNodes.py
--- a/Cython/Compiler/ExprNodes.py	Thu Apr 23 20:08:25 2009 +0200
+++ b/Cython/Compiler/ExprNodes.py	Sat Apr 25 20:58:37 2009 +0200
@@ -3003,11 +3003,12 @@ class SequenceNode(NewTempExprNode):
     
     def allocate_target_temps(self, env, rhs):
         self.iterator.allocate_temps(env)
-        for arg, node in zip(self.args, self.coerced_unpacked_items):
+        for node in self.coerced_unpacked_items:
             node.allocate_temps(env)
-            arg.allocate_target_temps(env, None)
             #arg.release_target_temp(env)
             #node.release_temp(env)
+        for arg in self.args:
+            arg.allocate_target_temps(env, None)
         if rhs:
             rhs.release_temp(env)
         self.iterator.release_temp(env)
diff -r c3bf82e34e54 -r 4179f49ac82d tests/run/tupleunpack_Thmm.pyx
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/run/tupleunpack_Thmm.pyx	Sat Apr 25 20:58:37 2009 +0200
@@ -0,0 +1,25 @@
+"""
+>>> func()
+0 0
+0
+0
+1 1
+1
+1
+2 2
+2
+2
+>>> func2()
+"""
+
+def g():
+    return ((3, 2), 1, 0)
+
+def func2():
+    (a, b), c, d = g()
+
+def func():
+    for (a, b),c ,d in zip(zip(range(3), range(3)), range(3), range(3)):
+        print a, b
+        print c
+        print d
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to