Kaydet (Commit) ddc4fd03 authored tarafından Jeremy Hylton's avatar Jeremy Hylton

Fix 2.1 nested scopes crash reported by Evan Simpson

The new test case demonstrates the bug.  Be more careful in
symtable_resolve_free() to add a var to cells or frees only if it
won't be added under some other rule.

XXX Add new assertion that will catch this bug.
üst 960d948e
......@@ -17,3 +17,4 @@ test_scope
16. check leaks
17. class and global
18. verify that locals() works
19. var is bound and free in class
......@@ -436,3 +436,14 @@ verify(d.has_key('h'))
del d['h']
verify(d == {'x': 2, 'y': 7, 'w': 6})
print "19. var is bound and free in class"
def f(x):
class C:
def m(self):
return x
a = x
return C
inst = f(3)()
verify(inst.a == inst.m())
......@@ -4057,7 +4057,7 @@ symtable_init_info(struct symbol_info *si)
}
static int
symtable_resolve_free(struct compiling *c, PyObject *name,
symtable_resolve_free(struct compiling *c, PyObject *name, int flags,
struct symbol_info *si)
{
PyObject *dict, *v;
......@@ -4067,11 +4067,19 @@ symtable_resolve_free(struct compiling *c, PyObject *name,
cell var). If it occurs in a class, then the class has a
method and a free variable with the same name.
*/
if (c->c_symtable->st_cur->ste_type == TYPE_FUNCTION) {
/* If it isn't declared locally, it can't be a cell. */
if (!(flags & (DEF_LOCAL | DEF_PARAM)))
return 0;
v = PyInt_FromLong(si->si_ncells++);
dict = c->c_cellvars;
} else {
/* If it is free anyway, then there is no need to do
anything here.
*/
if (is_free(flags ^ DEF_FREE_CLASS)
|| flags == DEF_FREE_CLASS)
return 0;
v = PyInt_FromLong(si->si_nfrees++);
dict = c->c_freevars;
}
......@@ -4357,10 +4365,7 @@ symtable_load_symbols(struct compiling *c)
variables or declared global.
*/
if (flags & (DEF_FREE | DEF_FREE_CLASS)) {
if ((ste->ste_type == TYPE_CLASS
&& flags != DEF_FREE_CLASS)
|| (flags & (DEF_LOCAL | DEF_PARAM)))
symtable_resolve_free(c, name, &si);
symtable_resolve_free(c, name, flags, &si);
}
if (flags & DEF_STAR) {
......@@ -4420,6 +4425,15 @@ symtable_load_symbols(struct compiling *c)
}
}
/*
fprintf(stderr,
"cells %d: %s\n"
"frees %d: %s\n",
si.si_ncells, PyObject_REPR(c->c_cellvars),
si.si_nfrees, PyObject_REPR(c->c_freevars));
*/
assert(PyDict_Size(c->c_freevars) == si.si_nfrees);
if (si.si_ncells > 1) { /* one cell is always in order */
if (symtable_cellvar_offsets(&c->c_cellvars, c->c_argcount,
c->c_varnames, c->c_flags) < 0)
......
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