diff options
author | Victor Stinner <vstinner@python.org> | 2021-01-30 00:46:44 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-30 00:46:44 (GMT) |
commit | ba7a99ddb52a45c8dec1f7e9f1648add0ace82ab (patch) | |
tree | 5a7b09325e6c2038ecc0a67e9354baf3ad7bc044 /Python | |
parent | 7fdab8331b90e1ffcedef05a006b6e72457b793a (diff) | |
download | cpython-ba7a99ddb52a45c8dec1f7e9f1648add0ace82ab.zip cpython-ba7a99ddb52a45c8dec1f7e9f1648add0ace82ab.tar.gz cpython-ba7a99ddb52a45c8dec1f7e9f1648add0ace82ab.tar.bz2 |
bpo-38631: Replace compiler fatal errors with exceptions (GH-24369)
* Replace Py_FatalError() calls with regular SystemError exceptions.
* compiler_exit_scope() calls _PyErr_WriteUnraisableMsg() to log the
PySequence_DelItem() failure.
* compiler_unit_check() uses _PyMem_IsPtrFreed().
* compiler_make_closure(): remove "(reftype == FREE)" comment since
reftype can also be LOCAL or GLOBAL_EXPLICIT.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/compile.c | 86 |
1 files changed, 52 insertions, 34 deletions
diff --git a/Python/compile.c b/Python/compile.c index 5d06a83..8abb5bb 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -22,6 +22,7 @@ */ #include "Python.h" +#include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_long.h" // _PyLong_GetZero() #include "Python-ast.h" @@ -520,9 +521,7 @@ compiler_unit_check(struct compiler_unit *u) { basicblock *block; for (block = u->u_blocks; block != NULL; block = block->b_list) { - assert((uintptr_t)block != 0xcbcbcbcbU); - assert((uintptr_t)block != 0xfbfbfbfbU); - assert((uintptr_t)block != 0xdbdbdbdbU); + assert(!_PyMem_IsPtrFreed(block)); if (block->b_instr != NULL) { assert(block->b_ialloc > 0); assert(block->b_iused >= 0); @@ -681,7 +680,8 @@ compiler_exit_scope(struct compiler *c) assert(c->u); /* we are deleting from a list so this really shouldn't fail */ if (PySequence_DelItem(c->c_stack, n) < 0) { - Py_FatalError("PySequence_DelItem failed"); + _PyErr_WriteUnraisableMsg("on removing the last compiler " + "stack item", NULL); } compiler_unit_check(c->u); } @@ -1898,17 +1898,15 @@ get_ref_type(struct compiler *c, PyObject *name) return CELL; scope = PyST_GetScope(c->u->u_ste, name); if (scope == 0) { - _Py_FatalErrorFormat(__func__, - "unknown scope for %.100s in %.100s(%s)\n" - "symbols: %s\nlocals: %s\nglobals: %s", - PyUnicode_AsUTF8(name), - PyUnicode_AsUTF8(c->u->u_name), - PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_id)), - PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_symbols)), - PyUnicode_AsUTF8(PyObject_Repr(c->u->u_varnames)), - PyUnicode_AsUTF8(PyObject_Repr(c->u->u_names))); + PyErr_Format(PyExc_SystemError, + "PyST_GetScope(name=%R) failed: " + "unknown scope in unit %S (%R); " + "symbols: %R; locals: %R; globals: %R", + name, + c->u->u_name, c->u->u_ste->ste_id, + c->u->u_ste->ste_symbols, c->u->u_varnames, c->u->u_names); + return -1; } - return scope; } @@ -1923,7 +1921,8 @@ compiler_lookup_arg(PyObject *dict, PyObject *name) } static int -compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, PyObject *qualname) +compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, + PyObject *qualname) { Py_ssize_t i, free = PyCode_GetNumFree(co); if (qualname == NULL) @@ -1935,7 +1934,6 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, Py LOAD_DEREF but LOAD_CLOSURE is needed. */ PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); - int arg, reftype; /* Special case: If a class contains a method with a free variable that has the same name as a method, @@ -1943,20 +1941,27 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, Py class. It should be handled by the closure, as well as by the normal name lookup logic. */ - reftype = get_ref_type(c, name); - if (reftype == CELL) + int reftype = get_ref_type(c, name); + if (reftype == -1) { + return 0; + } + int arg; + if (reftype == CELL) { arg = compiler_lookup_arg(c->u->u_cellvars, name); - else /* (reftype == FREE) */ + } + else { arg = compiler_lookup_arg(c->u->u_freevars, name); + } if (arg == -1) { - _Py_FatalErrorFormat(__func__, - "lookup %s in %s %d %d\n" - "freevars of %s: %s\n", - PyUnicode_AsUTF8(PyObject_Repr(name)), - PyUnicode_AsUTF8(c->u->u_name), - reftype, arg, - PyUnicode_AsUTF8(co->co_name), - PyUnicode_AsUTF8(PyObject_Repr(co->co_freevars))); + PyErr_Format(PyExc_SystemError, + "compiler_lookup_arg(name=%R) with reftype=%d failed in %S; " + "freevars of code %S: %R", + name, + reftype, + c->u->u_name, + co->co_name, + co->co_freevars); + return 0; } ADDOP_I(c, LOAD_CLOSURE, arg); } @@ -2294,7 +2299,11 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) return 0; } - compiler_make_closure(c, co, funcflags, qualname); + if (!compiler_make_closure(c, co, funcflags, qualname)) { + Py_DECREF(qualname); + Py_DECREF(co); + return 0; + } Py_DECREF(qualname); Py_DECREF(co); @@ -2419,7 +2428,10 @@ compiler_class(struct compiler *c, stmt_ty s) ADDOP(c, LOAD_BUILD_CLASS); /* 3. load a function (or closure) made from the code object */ - compiler_make_closure(c, co, 0, NULL); + if (!compiler_make_closure(c, co, 0, NULL)) { + Py_DECREF(co); + return 0; + } Py_DECREF(co); /* 4. load class name */ @@ -2697,7 +2709,11 @@ compiler_lambda(struct compiler *c, expr_ty e) return 0; } - compiler_make_closure(c, co, funcflags, qualname); + if (!compiler_make_closure(c, co, funcflags, qualname)) { + Py_DECREF(qualname); + Py_DECREF(co); + return 0; + } Py_DECREF(qualname); Py_DECREF(co); @@ -4660,8 +4676,9 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, if (co == NULL) goto error; - if (!compiler_make_closure(c, co, 0, qualname)) + if (!compiler_make_closure(c, co, 0, qualname)) { goto error; + } Py_DECREF(qualname); Py_DECREF(co); @@ -5468,8 +5485,10 @@ stackdepth(struct compiler *c) struct instr *instr = &b->b_instr[i]; int effect = stack_effect(instr->i_opcode, instr->i_oparg, 0); if (effect == PY_INVALID_STACK_EFFECT) { - _Py_FatalErrorFormat(__func__, - "opcode = %d", instr->i_opcode); + PyErr_Format(PyExc_SystemError, + "compiler stack_effect(opcode=%d, arg=%i) failed", + instr->i_opcode, instr->i_oparg); + return -1; } int new_depth = depth + effect; if (new_depth > maxdepth) { @@ -6675,4 +6694,3 @@ PyCode_Optimize(PyObject *code, PyObject* Py_UNUSED(consts), Py_INCREF(code); return code; } - |