diff Python/ast.c @ 39872:b8cb7201379c legacy-trunk

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.
author Neal Norwitz <nnorwitz@gmail.com>
date Fri, 22 Sep 2006 08:18:10 +0000
parents b8fbd322760a
children ebaf347d42fb
line wrap: on
line diff
--- a/Python/ast.c	Fri Sep 22 08:16:26 2006 +0000
+++ b/Python/ast.c	Fri Sep 22 08:18:10 2006 +0000
@@ -560,10 +560,17 @@
     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 @@
                        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 @@
         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 @@
                         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) {