gcc-python-plugin icon indicating copy to clipboard operation
gcc-python-plugin copied to clipboard

spurious report for "set" method

Open davidmalcolm opened this issue 8 years ago • 1 comments

Consider this source code, derived from an example in the Python manual: {{{ #include <Python.h> #include "structmember.h"

typedef struct { PyObject_HEAD PyObject *first; PyObject *last; int number; } Noddy;

extern void Noddy_dealloc(Noddy* self); extern PyObject *Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds); extern int Noddy_init(Noddy *self, PyObject *args, PyObject *kwds);

static PyObject * Noddy_getfirst(Noddy *self, void *closure) { Py_INCREF(self->first); return self->first; }

static int Noddy_setfirst(Noddy *self, PyObject *value, void *closure) { if (value == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute"); return -1; }

if (! PyString_Check(value)) { PyErr_SetString(PyExc_TypeError, "The first attribute value must be a string"); return -1; }

Py_DECREF(self->first); Py_INCREF(value); self->first = value;

return 0; }

static PyGetSetDef Noddy_getseters[] = { {"first", (getter)Noddy_getfirst, (setter)Noddy_setfirst, "first name", NULL},

{NULL} /* Sentinel */ };

static PyTypeObject NoddyType = { PyObject_HEAD_INIT(NULL) 0, /ob_size/ "noddy.Noddy", /tp_name/ sizeof(Noddy), /tp_basicsize/ 0, /tp_itemsize/ (destructor)Noddy_dealloc, /tp_dealloc/ 0, /tp_print/ 0, /tp_getattr/ 0, /tp_setattr/ 0, /tp_compare/ 0, /tp_repr/ 0, /tp_as_number/ 0, /tp_as_sequence/ 0, /tp_as_mapping/ 0, /*tp_hash / 0, /tp_call/ 0, /tp_str/ 0, /tp_getattro/ 0, /tp_setattro/ 0, /tp_as_buffer/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /tp_flags/ "Noddy objects", / tp_doc / 0, / tp_traverse / 0, / tp_clear / 0, / tp_richcompare / 0, / tp_weaklistoffset / 0, / tp_iter / 0, / tp_iternext / NULL, / tp_methods / NULL, / tp_members / Noddy_getseters, / tp_getset / 0, / tp_base / 0, / tp_dict / 0, / tp_descr_get / 0, / tp_descr_set / 0, / tp_dictoffset / (initproc)Noddy_init, / tp_init / 0, / tp_alloc / Noddy_new, / tp_new */ }; }}}

I think it is correct, but the checker gives errors:

{{{ setter.c: In function ‘Noddy_setfirst’: setter.c:42:1: warning: ob_refcnt of '*value' is 1 too high [enabled by default] setter.c:42:1: note: was expecting final ob_refcnt to be N + 0 (for some unknown N) setter.c:42:1: note: but final ob_refcnt is N + 1 setter.c:26:6: note: taking False path at: if (value == NULL) { setter.c:31:9: note: reaching: if (! PyString_Check(value)) { setter.c:31:6: note: when considering range: 1 <= value <= 0x8000000 at: if (! PyString_Check(value)) { setter.c:31:6: note: taking False path at: if (! PyString_Check(value)) { setter.c:37:3: note: reaching: Py_DECREF(self->first); setter.c:37:3: note: when treating unknown struct PyObject * from setter.c:37 as non-NULL at: Py_DECREF(self->first); setter.c:37:3: note: when considering range: -0x8000000000000000 <= value <= -1 at: Py_DECREF(self->first); setter.c:37:3: note: taking True path at: Py_DECREF(self->first); setter.c:38:3: note: reaching: Py_INCREF(value); setter.c:38:3: note: ob_refcnt is now refs: 1 + N where N >= 1 setter.c:42:1: note: returning setter.c:42:1: note: found 2 similar trace(s) to this setter.c:25:1: note: graphical error report for function 'Noddy_setfirst' written out to 'setter.c.Noddy_setfirst-refcount-errors.html' }}}

davidmalcolm avatar Feb 09 '17 20:02 davidmalcolm

Imported from trac issue 47. Created by tromey on 2013-04-17T16:05:07, last modified: 2013-04-17T16:05:07

davidmalcolm avatar Feb 09 '17 20:02 davidmalcolm