Stefan Behnel wrote:
> Hugues Salamin wrote:
>> The following code will crash with a segfault when compiled using cython 
>> (v0.11)
>>
>> 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 # This line segfault
>>
>> Compilation is done using distutils.
>>
>> If the module is imported in python and func is called, I got a segmentation
>> fault at the line "print d".
> 
> Yes, this works for me in the latest (unstable) developer branch, but fails
> in the release branch:
> 
>   $ cd cython-unstable
>   $ cat rangeloop.pyx
>   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 # This line segfault
> 
>   $ python2.6 -c 'import pyximport; pyximport.install(); \
>                                  import rangeloop; rangeloop.func()'
>   0 0
>   0
>   0
>   1 1
>   1
>   1
>   2 2
>   2
>   2
> 
>   $ cd ../cython-release
>   $ python2.6 -c 'import pyximport; pyximport.install(); \
>                                  import rangeloop; rangeloop.func()'
>   0 0
>   0
>   Segmentation fault


The generated code is incorrect in this case. Note how the (old-style) temp
var __pyx_4 is used for both the 'a' and 'd' variables.

    if (PyTuple_CheckExact(__pyx_t_5) && \
                        likely(PyTuple_GET_SIZE(__pyx_t_5) == 3)) {
      PyObject* tuple = __pyx_t_5;
      __pyx_2 = PyTuple_GET_ITEM(tuple, 0); __Pyx_INCREF(__pyx_2);
      __pyx_3 = PyTuple_GET_ITEM(tuple, 1); __Pyx_INCREF(__pyx_3);
      __pyx_4 = PyTuple_GET_ITEM(tuple, 2); __Pyx_INCREF(__pyx_4);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      if (PyTuple_CheckExact(__pyx_2) && \
                          likely(PyTuple_GET_SIZE(__pyx_2) == 2)) {
        PyObject* tuple = __pyx_2;
        __pyx_4 = PyTuple_GET_ITEM(tuple, 0); __Pyx_INCREF(__pyx_4);
        __pyx_5 = PyTuple_GET_ITEM(tuple, 1); __Pyx_INCREF(__pyx_5);
        __Pyx_DECREF(__pyx_2); __pyx_2 = 0;
        __Pyx_DECREF(__pyx_v_a);
        __pyx_v_a = __pyx_4;
        __pyx_4 = 0;
        __Pyx_DECREF(__pyx_v_b);
        __pyx_v_b = __pyx_5;
        __pyx_5 = 0;

      ...

      }
      __Pyx_DECREF(__pyx_v_c);
      __pyx_v_c = __pyx_3;
      __pyx_3 = 0;
      __Pyx_DECREF(__pyx_v_d);
      __pyx_v_d = __pyx_4;
      __pyx_4 = 0;

Given that this works in cython-unstable (and I know that there were many,
many changes regarding temp allocation there again, it now uses new-style
temps everywhere), the backport may not be as simple as "copy one line".

Dag, any idea?

Stefan
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to