summaryrefslogtreecommitdiff
path: root/Python
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2006-09-25 07:04:10 +0000
committerGeorg Brandl <georg@python.org>2006-09-25 07:04:10 +0000
commitc57221e15809e66b499bdd23f07fdda972b163fc (patch)
treea5c6820f8d8f3e22ade3ea6229623e60c0630a57 /Python
parent934c90de0de8a0fd5f07b483b18d98beb857dbd9 (diff)
downloadcpython-git-c57221e15809e66b499bdd23f07fdda972b163fc.tar.gz
Backport rev. 51972:
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.
Diffstat (limited to 'Python')
-rw-r--r--Python/ast.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/Python/ast.c b/Python/ast.c
index 4d0b991c2c..52c098ff3b 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -566,10 +566,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");
@@ -579,7 +586,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);
}
@@ -637,6 +654,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? */
@@ -662,7 +680,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
+ upacking mixed in. */
ch = CHILD(ch, 0);
+ assert(TYPE(ch) == fpdef);
+ goto handle_fpdef;
}
}
if (TYPE(CHILD(ch, 0)) == NAME) {