Hi,
I compiled gmpy2 (a wrapper for GMP, MPFR, and MPC) with
gcc-with-cpychecker. It found several reference counting bugs and a
few missing checks for NULL return values.
I am seeing an AssertionError in absinterp.py. It occurs repeatedly.
The first instance is:
In file included from src/gmpy2.c:452:0:
src/gmpy_mpz.c: In function ‘Pyxmpz_digits’:
src/gmpy_mpz.c:188:5: error: Unhandled Python exception raised calling
'execute' method
Traceback (most recent call last):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/__init__.py",
line 66, in execute
self._check_refcounts(fun)
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/__init__.py",
line 70, in _check_refcounts
self.show_possible_null_derefs)
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/refcounts.py",
line 3198, in check_refcounts
limits=limits)
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2896, in iter_traces
depth + 1):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2896, in iter_traces
depth + 1):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2896, in iter_traces
depth + 1):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2896, in iter_traces
depth + 1):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2896, in iter_traces
depth + 1):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2896, in iter_traces
depth + 1):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2896, in iter_traces
depth + 1):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2896, in iter_traces
depth + 1):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2896, in iter_traces
depth + 1):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2896, in iter_traces
depth + 1):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2896, in iter_traces
depth + 1):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2896, in iter_traces
depth + 1):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2896, in iter_traces
depth + 1):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2896, in iter_traces
depth + 1):
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2860, in iter_traces
transitions = curstate.get_transitions()
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2007, in get_transitions
return self._get_transitions_for_stmt(stmt)
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2023, in _get_transitions_for_stmt
return self._get_transitions_for_GimpleCall(stmt)
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2187, in _get_transitions_for_GimpleCall
return meth(stmt, *args)
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/refcounts.py",
line 1392, in impl_PyErr_SetString
t_next = self.state.mktrans_nop(stmt, 'PyErr_SetString')
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 2085, in mktrans_nop
newstate.loc = self.loc.next_loc()
File "/usr/lib/gcc/x86_64-redhat-linux/4.7.0/plugin/python2/libcpychecker/absinterp.py",
line 1113, in next_loc
assert len(self.bb.succs) == 1
AssertionError
Line 188 is a call to this macro:
#define PARSE_ONE_MPZ_OPT_CLONG(var, msg) \
if (self && CHECK_MPZANY(self)) { \
if (PyTuple_GET_SIZE(args) == 1) { \
*var = clong_From_Integer(PyTuple_GET_ITEM(args, 0)); \
if (*var == -1 && PyErr_Occurred()) { \
PyErr_SetString(PyExc_TypeError, msg); \
return NULL; \
} \
} \
else if (PyTuple_GET_SIZE(args) > 1) { \
PyErr_SetString(PyExc_TypeError, msg); \
return NULL; \
} \
Py_INCREF(self); \
} \
else { \
if (PyTuple_GET_SIZE(args) == 2) { \
*var = clong_From_Integer(PyTuple_GET_ITEM(args, 1)); \
if (*var == -1 && PyErr_Occurred()) { \
PyErr_SetString(PyExc_TypeError, msg); \
return NULL; \
} \
self = PyTuple_GET_ITEM(args, 0); \
if (CHECK_MPZANY(self)) { \
Py_INCREF((PyObject*)self); \
} \
else { \
self =
(PyObject*)Pympz_From_Integer(PyTuple_GET_ITEM(args, 0)); \
} \
} \
else if (PyTuple_GET_SIZE(args) == 1) { \
self = PyTuple_GET_ITEM(args, 0); \
if (CHECK_MPZANY(self)) { \
Py_INCREF((PyObject*)self); \
} \
else { \
self =
(PyObject*)Pympz_From_Integer(PyTuple_GET_ITEM(args, 0)); \
} \
} \
else { \
PyErr_SetString(PyExc_TypeError, msg); \
return NULL; \
} \
if (!self) { \
PyErr_SetString(PyExc_TypeError, msg); \
return NULL; \
} \
}
Interestingly, this is the second invocation of this macro in
gmpy2_mpz.c The previous invocation occurs on line 175 and doesn't
generate an exception.
Please let me know if you need more information.
casevh