From: Serhiy Storchaka Date: Wed, 15 Jun 2016 17:07:53 +0000 (+0300) Subject: Issue #27301: Fixed incorrect return codes for errors in compile.c. X-Git-Tag: v3.6.0a3~137 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=607f8a5e283df80eb155341b08251eb5d31be075;p=python Issue #27301: Fixed incorrect return codes for errors in compile.c. --- 607f8a5e283df80eb155341b08251eb5d31be075 diff --cc Python/compile.c index efb6c7ee3e,ce510aa731..687b7506bf --- a/Python/compile.c +++ b/Python/compile.c @@@ -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; @@@ -1662,47 -1592,38 +1667,56 @@@ } 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) { @@@ -1714,11 -1635,12 +1728,11 @@@ 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); @@@ -1743,23 -1665,25 +1757,23 @@@ 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);