diff options
author | Neal Norwitz <nnorwitz@gmail.com> | 2006-09-22 08:18:10 (GMT) |
---|---|---|
committer | Neal Norwitz <nnorwitz@gmail.com> | 2006-09-22 08:18:10 (GMT) |
commit | 3a23017bb2309f6ba44090fb322f9681bf49c4c3 (patch) | |
tree | ffd83e481bb8e27942977b4ec7110e6d570ede04 /Python/ast.c | |
parent | 4a8fbdb1b2172e1954e652be7dda74d188a00fa5 (diff) | |
download | cpython-3a23017bb2309f6ba44090fb322f9681bf49c4c3.zip cpython-3a23017bb2309f6ba44090fb322f9681bf49c4c3.tar.gz cpython-3a23017bb2309f6ba44090fb322f9681bf49c4c3.tar.bz2 |
Bug #1557232: fix seg fault with def f((((x)))) and def f(((x),)).
These tests should be improved. Hopefully this fixes variations when
flipping back and forth between fpdef and fplist.
Backport candidate.
Diffstat (limited to 'Python/ast.c')
-rw-r--r-- | Python/ast.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/Python/ast.c b/Python/ast.c index 9e0c184..f490268 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -560,10 +560,17 @@ compiler_complex_args(struct compiling *c, const node *n) if (!args) return NULL; + /* fpdef: NAME | '(' fplist ')' + fplist: fpdef (',' fpdef)* [','] + */ REQ(n, fplist); for (i = 0; i < len; i++) { - const node *child = CHILD(CHILD(n, 2*i), 0); + const node *fpdef_node = CHILD(n, 2*i); + const node *child; expr_ty arg; +set_name: + /* fpdef_node is either a NAME or an fplist */ + child = CHILD(fpdef_node, 0); if (TYPE(child) == NAME) { if (!strcmp(STR(child), "None")) { ast_error(child, "assignment to None"); @@ -573,7 +580,17 @@ compiler_complex_args(struct compiling *c, const node *n) child->n_col_offset, c->c_arena); } else { - arg = compiler_complex_args(c, CHILD(CHILD(n, 2*i), 1)); + assert(TYPE(fpdef_node) == fpdef); + /* fpdef_node[0] is not a name, so it must be a '(', get CHILD[1] */ + child = CHILD(fpdef_node, 1); + assert(TYPE(child) == fplist); + /* NCH == 1 means we have (x), we need to elide the extra parens */ + if (NCH(child) == 1) { + fpdef_node = CHILD(child, 0); + assert(TYPE(fpdef_node) == fpdef); + goto set_name; + } + arg = compiler_complex_args(c, child); } asdl_seq_SET(args, i, arg); } @@ -631,6 +648,7 @@ ast_for_arguments(struct compiling *c, const node *n) ch = CHILD(n, i); switch (TYPE(ch)) { case fpdef: + handle_fpdef: /* XXX Need to worry about checking if TYPE(CHILD(n, i+1)) is anything other than EQUAL or a comma? */ /* XXX Should NCH(n) check be made a separate check? */ @@ -656,7 +674,11 @@ ast_for_arguments(struct compiling *c, const node *n) asdl_seq_SET(args, k++, compiler_complex_args(c, ch)); } else { /* def foo((x)): setup for checking NAME below. */ + /* Loop because there can be many parens and tuple + unpacking mixed in. */ ch = CHILD(ch, 0); + assert(TYPE(ch) == fpdef); + goto handle_fpdef; } } if (TYPE(CHILD(ch, 0)) == NAME) { |