]> granicus.if.org Git - python/commitdiff
Issue #27301: Fixed incorrect return codes for errors in compile.c.
authorSerhiy Storchaka <storchaka@gmail.com>
Wed, 15 Jun 2016 17:07:53 +0000 (20:07 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Wed, 15 Jun 2016 17:07:53 +0000 (20:07 +0300)
1  2 
Python/compile.c

index efb6c7ee3e22f6e5ef8284aa144ae863e4523ce9,ce510aa731223058e6b4b3f498ffcd8e6c46ef2b..687b7506bf70e946c5818bf7c9369952e2987da1
@@@ -1536,55 -1494,26 +1536,60 @@@ static in
  compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs,
                                asdl_seq *kw_defaults)
  {
 -    /* Return the number of defaults + 1.
 -       Returns 0 on error.
 -     */
 -    int i, default_count = 0;
++    /* Push a dict of keyword-only default values.
++
++       Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed.
++       */
 +    int i;
 +    PyObject *keys = NULL;
 +
      for (i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
          arg_ty arg = asdl_seq_GET(kwonlyargs, i);
          expr_ty default_ = asdl_seq_GET(kw_defaults, i);
          if (default_) {
              PyObject *mangled = _Py_Mangle(c->u->u_private, arg->arg);
 -            if (!mangled)
 -                return 0;
 -            ADDOP_O(c, LOAD_CONST, mangled, consts);
 -            Py_DECREF(mangled);
 +            if (!mangled) {
 +                goto error;
 +            }
 +            if (keys == NULL) {
 +                keys = PyList_New(1);
 +                if (keys == NULL) {
 +                    Py_DECREF(mangled);
-                     return -1;
++                    return 0;
 +                }
 +                PyList_SET_ITEM(keys, 0, mangled);
 +            }
 +            else {
 +                int res = PyList_Append(keys, mangled);
 +                Py_DECREF(mangled);
 +                if (res == -1) {
 +                    goto error;
 +                }
 +            }
              if (!compiler_visit_expr(c, default_)) {
 -                return 0;
 +                goto error;
              }
 -            default_count++;
          }
      }
 -    return default_count + 1;
 +    if (keys != NULL) {
 +        Py_ssize_t default_count = PyList_GET_SIZE(keys);
 +        PyObject *keys_tuple = PyList_AsTuple(keys);
 +        Py_DECREF(keys);
 +        if (keys_tuple == NULL) {
-             return -1;
++            return 0;
 +        }
 +        ADDOP_N(c, LOAD_CONST, keys_tuple, consts);
 +        ADDOP_I(c, BUILD_CONST_KEY_MAP, default_count);
-         return default_count;
++        assert(default_count > 0);
++        return 1;
 +    }
 +    else {
-         return 0;
++        return -1;
 +    }
 +
 +error:
 +    Py_XDECREF(keys);
-     return -1;
++    return 0;
  }
  
  static int
@@@ -1627,10 -1556,11 +1632,10 @@@ static in
  compiler_visit_annotations(struct compiler *c, arguments_ty args,
                             expr_ty returns)
  {
-     /* Push arg annotation dict.  Return # of items pushed.
 -    /* Push arg annotations and a list of the argument names. Return the #
 -       of items pushed + 1. The expressions are evaluated out-of-order wrt the
 -       source code.
++    /* Push arg annotation dict.
 +       The expressions are evaluated out-of-order wrt the source code.
  
-        Returns -1 on error.
 -       More than 2^16-1 annotations is a SyntaxError. Returns 0 on error.
++       Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed.
         */
      static identifier return_str;
      PyObject *names;
      }
  
      len = PyList_GET_SIZE(names);
 -    if (len > 65534) {
 -        /* len must fit in 16 bits, and len is incremented below */
 -        PyErr_SetString(PyExc_SyntaxError,
 -                        "too many annotations");
 -        goto error;
 -    }
      if (len) {
 -        /* convert names to a tuple and place on stack */
 -        PyObject *elt;
 -        Py_ssize_t i;
 -        PyObject *s = PyTuple_New(len);
 -        if (!s)
 -            goto error;
 -        for (i = 0; i < len; i++) {
 -            elt = PyList_GET_ITEM(names, i);
 -            Py_INCREF(elt);
 -            PyTuple_SET_ITEM(s, i, elt);
 +        PyObject *keytuple = PyList_AsTuple(names);
 +        Py_DECREF(names);
 +        if (keytuple == NULL) {
-             return -1;
++            return 0;
          }
 -        ADDOP_O(c, LOAD_CONST, s, consts);
 -        Py_DECREF(s);
 -        len++; /* include the just-pushed tuple */
 +        ADDOP_N(c, LOAD_CONST, keytuple, consts);
 +        ADDOP_I(c, BUILD_CONST_KEY_MAP, len);
++        return 1;
 +    }
 +    else {
 +        Py_DECREF(names);
++        return -1;
      }
-     return len;
 -    Py_DECREF(names);
 -
 -    /* We just checked that len <= 65535, see above */
 -    return Py_SAFE_DOWNCAST(len + 1, Py_ssize_t, int);
  
  error:
      Py_DECREF(names);
-     return -1;
+     return 0;
+ }
++static int
++compiler_visit_defaults(struct compiler *c, arguments_ty args)
++{
++    VISIT_SEQ(c, expr, args->defaults);
++    ADDOP_I(c, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
++    return 1;
 +}
 +
 +static Py_ssize_t
 +compiler_default_arguments(struct compiler *c, arguments_ty args)
 +{
 +    Py_ssize_t funcflags = 0;
 +    if (args->defaults && asdl_seq_LEN(args->defaults) > 0) {
-         VISIT_SEQ(c, expr, args->defaults);
-         ADDOP_I(c, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
++        if (!compiler_visit_defaults(c, args))
++            return -1;
 +        funcflags |= 0x01;
 +    }
 +    if (args->kwonlyargs) {
-         Py_ssize_t res = compiler_visit_kwonlydefaults(c, args->kwonlyargs,
++        int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs,
 +                                                args->kw_defaults);
-         if (res < 0) {
++        if (res == 0) {
 +            return -1;
 +        }
 +        else if (res > 0) {
 +            funcflags |= 0x02;
 +        }
 +    }
 +    return funcflags;
 +}
 +
  static int
  compiler_function(struct compiler *c, stmt_ty s, int is_async)
  {
      asdl_seq* decos;
      asdl_seq *body;
      stmt_ty st;
 -    Py_ssize_t i, n, arglength;
 -    int docstring, kw_default_count = 0;
 -    int num_annotations;
 +    Py_ssize_t i, n, funcflags;
 +    int docstring;
-     int num_annotations;
++    int annotations;
      int scope_type;
  
 -
      if (is_async) {
          assert(s->kind == AsyncFunctionDef_kind);
  
  
      if (!compiler_decorators(c, decos))
          return 0;
 -    if (args->defaults)
 -        VISIT_SEQ(c, expr, args->defaults);
 -    if (args->kwonlyargs) {
 -        int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs,
 -                                                args->kw_defaults);
 -        if (res == 0)
 -            return 0;
 -        kw_default_count = res - 1;
 +
 +    funcflags = compiler_default_arguments(c, args);
 +    if (funcflags == -1) {
 +        return 0;
      }
 -    num_annotations = compiler_visit_annotations(c, args, returns);
 -    if (num_annotations == 0)
 +
-     num_annotations = compiler_visit_annotations(c, args, returns);
-     if (num_annotations < 0) {
++    annotations = compiler_visit_annotations(c, args, returns);
++    if (annotations == 0) {
          return 0;
 -    num_annotations--;
 -    assert((num_annotations & 0xFFFF) == num_annotations);
 +    }
-     else if (num_annotations > 0) {
++    else if (annotations > 0) {
 +        funcflags |= 0x04;
 +    }
  
 -    if (!compiler_enter_scope(c, name,
 -                              scope_type, (void *)s,
 -                              s->lineno))
 +    if (!compiler_enter_scope(c, name, scope_type, (void *)s, s->lineno)) {
          return 0;
 +    }
  
      st = (stmt_ty)asdl_seq_GET(body, 0);
      docstring = compiler_isdocstring(st);