Ticket #124 (closed defect: fixed)

Opened 2 months ago

Last modified 1 month ago

Misplaced decref due to PyDict_Next optimization

Reported by: jasone Assigned to: scoder
Priority: critical Milestone: 0.11
Component: Code Generation Version:
Keywords: Cc:

Description

The PyDict?_Next optimization looks like it might be conflicting with another optimization that collects local temp variables of the same type into a single variable... or something. Cython generates C code for the attached program that has a bogus Py_DECREF call, as indicated in the comments of the program. This can cause a crash (though that's only happening for me in the program that I first noticed the problem for).

Attachments

foo.pyx (0.7 kB) - added by jasone on 11/20/2008 10:54:40 AM.
foo.c (40.0 kB) - added by jasone on 11/20/2008 10:54:56 AM.

Change History

11/20/2008 10:54:40 AM changed by jasone

  • attachment foo.pyx added.

11/20/2008 10:54:56 AM changed by jasone

  • attachment foo.c added.

11/20/2008 11:30:36 AM changed by jasone

I just took a look at what was generated before the PyDict_Next optimization was added, and it looks like there was a temp variable used to store a PyList reference during iteration. That temp variable appears to be what the bogus Py_DECREF call is for.

11/25/2008 11:31:29 AM changed by scoder

  • owner changed from somebody to scoder.

11/26/2008 04:18:20 AM changed by scoder

  • priority changed from major to critical.

The problem is the return statement (ReturnStatNode?). In analyse_expressions(), it retrieves the list of active temps:

        self.temps_in_use = env.temps_in_use()

and then frees that in its execution code:

        for entry in self.temps_in_use:
            code.put_var_decref_clear(entry)

Like some other tree transforms, the iter-dict optimisation changes the temp allocation, which leaves some temps unused later in the code, such as the one for the loop iterator in your example. The return statement isn't prepared for that. So the impact of this bug is actually larger than just the iter-dict transform.

11/26/2008 04:23:03 AM changed by scoder

Here's a shorter example with the same problem:

def spam(dict d):
    for elm in d:
        return False
    return True

spam(dict(test=2))

11/29/2008 02:37:08 PM changed by dagss

  • status changed from new to closed.
  • resolution set to fixed.

11/29/2008 02:37:43 PM changed by dagss

More temp resolution stuff should be seen in relation to #77.