diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-04-27 02:29:40 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-04-27 02:29:40 (GMT) |
commit | ddc4fd03b1eadeab65f8e0dbf5b6f386ed419fbc (patch) | |
tree | 288c1648ee28f097444e9926b037e0295df0c71b /Python | |
parent | 960d948e7ce536eb30b69add0c6fc2dc31c90a8e (diff) | |
download | cpython-ddc4fd03b1eadeab65f8e0dbf5b6f386ed419fbc.zip cpython-ddc4fd03b1eadeab65f8e0dbf5b6f386ed419fbc.tar.gz cpython-ddc4fd03b1eadeab65f8e0dbf5b6f386ed419fbc.tar.bz2 |
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.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/compile.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/Python/compile.c b/Python/compile.c index cb85ce3..1f1d44c 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -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) |