diff -r 14cf0011c5e9 Include/pyerrors.h --- a/Include/pyerrors.h Fri Apr 15 10:51:46 2016 -0700 +++ b/Include/pyerrors.h Sat Apr 16 11:02:17 2016 +0300 @@ -293,6 +293,17 @@ PyAPI_FUNC(void) _PyErr_BadInternalCall( Python 2.0: */ #define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) +#ifdef Py_DEBUG +#define _Py_CHECK_NO_ERRORS(ret) do { \ + if (PyErr_Occurred()) { \ + PyErr_BadInternalCall(); \ + return (ret); \ + } \ + } while (0); +#else +#define _Py_CHECK_NO_ERRORS(ret) assert(!PyErr_Occurred()) +#endif + /* Function to create a new exception */ PyAPI_FUNC(PyObject *) PyErr_NewException( const char *name, PyObject *base, PyObject *dict); diff -r 14cf0011c5e9 Objects/abstract.c --- a/Objects/abstract.c Fri Apr 15 10:51:46 2016 -0700 +++ b/Objects/abstract.c Sat Apr 16 11:02:17 2016 +0300 @@ -2780,6 +2780,7 @@ PyObject * PyIter_Next(PyObject *iter) { PyObject *result; + _Py_CHECK_NO_ERRORS(NULL); result = (*iter->ob_type->tp_iternext)(iter); if (result == NULL && PyErr_Occurred() && diff -r 14cf0011c5e9 Objects/complexobject.c --- a/Objects/complexobject.c Fri Apr 15 10:51:46 2016 -0700 +++ b/Objects/complexobject.c Sat Apr 16 11:02:17 2016 +0300 @@ -292,17 +292,18 @@ PyComplex_AsCComplex(PyObject *op) Py_complex cv; PyObject *newop = NULL; + /* return -1 on failure */ + cv.real = -1.; + cv.imag = 0.; + assert(op); + _Py_CHECK_NO_ERRORS(cv); /* If op is already of type PyComplex_Type, return its value */ if (PyComplex_Check(op)) { return ((PyComplexObject *)op)->cval; } /* If not, use op's __complex__ method, if it exists */ - /* return -1 on failure */ - cv.real = -1.; - cv.imag = 0.; - newop = try_complex_special_method(op); if (newop) { diff -r 14cf0011c5e9 Objects/floatobject.c --- a/Objects/floatobject.c Fri Apr 15 10:51:46 2016 -0700 +++ b/Objects/floatobject.c Sat Apr 16 11:02:17 2016 +0300 @@ -218,13 +218,14 @@ PyFloat_AsDouble(PyObject *op) PyFloatObject *fo; double val; - if (op && PyFloat_Check(op)) - return PyFloat_AS_DOUBLE((PyFloatObject*) op); - if (op == NULL) { PyErr_BadArgument(); return -1; } + _Py_CHECK_NO_ERRORS(-1.0); + + if (PyFloat_Check(op)) + return PyFloat_AS_DOUBLE((PyFloatObject*) op); if ((nb = Py_TYPE(op)->tp_as_number) == NULL || nb->nb_float == NULL) { PyErr_SetString(PyExc_TypeError, "a float is required"); @@ -2279,6 +2280,7 @@ double double _PyFloat_Unpack8(const unsigned char *p, int le) { + _Py_CHECK_NO_ERRORS(-1.0); if (double_format == unknown_format) { unsigned char sign; int e; diff -r 14cf0011c5e9 Objects/longobject.c --- a/Objects/longobject.c Fri Apr 15 10:51:46 2016 -0700 +++ b/Objects/longobject.c Sat Apr 16 11:02:17 2016 +0300 @@ -403,6 +403,7 @@ PyLong_AsLongAndOverflow(PyObject *vv, i PyErr_BadInternalCall(); return -1; } + _Py_CHECK_NO_ERRORS(-1); if (PyLong_Check(vv)) { v = (PyLongObject *)vv; @@ -512,6 +513,7 @@ PyLong_AsSsize_t(PyObject *vv) { PyErr_BadInternalCall(); return -1; } + _Py_CHECK_NO_ERRORS(-1); if (!PyLong_Check(vv)) { PyErr_SetString(PyExc_TypeError, "an integer is required"); return -1; @@ -567,6 +569,7 @@ PyLong_AsUnsignedLong(PyObject *vv) PyErr_BadInternalCall(); return (unsigned long)-1; } + _Py_CHECK_NO_ERRORS(-1); if (!PyLong_Check(vv)) { PyErr_SetString(PyExc_TypeError, "an integer is required"); return (unsigned long)-1; @@ -611,6 +614,7 @@ PyLong_AsSize_t(PyObject *vv) PyErr_BadInternalCall(); return (size_t) -1; } + _Py_CHECK_NO_ERRORS(-1); if (!PyLong_Check(vv)) { PyErr_SetString(PyExc_TypeError, "an integer is required"); return (size_t)-1; @@ -683,6 +687,7 @@ PyLong_AsUnsignedLongMask(PyObject *op) PyErr_BadInternalCall(); return (unsigned long)-1; } + _Py_CHECK_NO_ERRORS(-1); if (PyLong_Check(op)) { return _PyLong_AsUnsignedLongMask(op); @@ -1202,6 +1207,7 @@ PyLong_AsLongLong(PyObject *vv) PyErr_BadInternalCall(); return -1; } + _Py_CHECK_NO_ERRORS(-1); if (PyLong_Check(vv)) { v = (PyLongObject *)vv; @@ -1253,6 +1259,7 @@ PyLong_AsUnsignedLongLong(PyObject *vv) PyErr_BadInternalCall(); return (unsigned PY_LONG_LONG)-1; } + _Py_CHECK_NO_ERRORS(-1); if (!PyLong_Check(vv)) { PyErr_SetString(PyExc_TypeError, "an integer is required"); return (unsigned PY_LONG_LONG)-1; @@ -1317,6 +1324,7 @@ PyLong_AsUnsignedLongLongMask(PyObject * PyErr_BadInternalCall(); return (unsigned long)-1; } + _Py_CHECK_NO_ERRORS(-1); if (PyLong_Check(op)) { return _PyLong_AsUnsignedLongLongMask(op); @@ -1357,6 +1365,7 @@ PyLong_AsLongLongAndOverflow(PyObject *v PyErr_BadInternalCall(); return -1; } + _Py_CHECK_NO_ERRORS(-1); if (PyLong_Check(vv)) { v = (PyLongObject *)vv; @@ -2654,6 +2663,7 @@ double multiple of 4, rounding ties to a multiple of 8. */ static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1}; + _Py_CHECK_NO_ERRORS(-1.0); a_size = Py_ABS(Py_SIZE(a)); if (a_size == 0) { /* Special case for 0: significand 0.0, exponent 0. */ @@ -2765,6 +2775,7 @@ PyLong_AsDouble(PyObject *v) PyErr_BadInternalCall(); return -1.0; } + _Py_CHECK_NO_ERRORS(-1.0); if (!PyLong_Check(v)) { PyErr_SetString(PyExc_TypeError, "an integer is required"); return -1.0; diff -r 14cf0011c5e9 Objects/typeobject.c --- a/Objects/typeobject.c Fri Apr 15 10:51:46 2016 -0700 +++ b/Objects/typeobject.c Sat Apr 16 11:02:17 2016 +0300 @@ -2852,6 +2852,7 @@ PyObject * PyObject *mro, *res, *base, *dict; unsigned int h; + _Py_CHECK_NO_ERRORS(NULL); if (MCACHE_CACHEABLE_NAME(name) && PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)) { /* fast path */ diff -r 14cf0011c5e9 Python/errors.c --- a/Python/errors.c Fri Apr 15 10:51:46 2016 -0700 +++ b/Python/errors.c Sat Apr 16 11:02:17 2016 +0300 @@ -746,9 +746,12 @@ PyErr_SetImportError(PyObject *msg, PyOb void _PyErr_BadInternalCall(const char *filename, int lineno) { + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); PyErr_Format(PyExc_SystemError, "%s:%d: bad argument to internal function", filename, lineno); + _PyErr_ChainExceptions(exc, val, tb); } /* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can diff -r 14cf0011c5e9 Python/marshal.c --- a/Python/marshal.c Fri Apr 15 10:51:46 2016 -0700 +++ b/Python/marshal.c Sat Apr 16 11:02:17 2016 +0300 @@ -747,6 +747,7 @@ r_short(RFILE *p) short x = -1; const unsigned char *buffer; + _Py_CHECK_NO_ERRORS(-1); buffer = (const unsigned char *) r_string(2, p); if (buffer != NULL) { x = buffer[0]; @@ -763,6 +764,7 @@ r_long(RFILE *p) long x = -1; const unsigned char *buffer; + _Py_CHECK_NO_ERRORS(-1); buffer = (const unsigned char *) r_string(4, p); if (buffer != NULL) { x = buffer[0]; diff -r 14cf0011c5e9 Python/pystrtod.c --- a/Python/pystrtod.c Fri Apr 15 10:51:46 2016 -0700 +++ b/Python/pystrtod.c Sat Apr 16 11:02:17 2016 +0300 @@ -341,6 +341,7 @@ PyOS_string_to_double(const char *s, double x, result=-1.0; char *fail_pos; + _Py_CHECK_NO_ERRORS(-1.0); errno = 0; PyFPE_START_PROTECT("PyOS_string_to_double", return -1.0) x = _PyOS_ascii_strtod(s, &fail_pos);