From 22edcd3d0ebaba0a199be172286617e7db7fe998 Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Fri, 28 Dec 2018 14:12:22 +0100 Subject: [PATCH] Added TO_STATE() marker to work around cpychecker refcount issue See davidmalcolm/gcc-python-plugin#109 --- psycopg/connection_int.c | 2 +- psycopg/connection_type.c | 8 ++++---- psycopg/utils.c | 16 ++++++++++++++++ psycopg/utils.h | 6 ++++++ 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c index 7875b13a..5d148df3 100644 --- a/psycopg/connection_int.c +++ b/psycopg/connection_int.c @@ -1392,7 +1392,7 @@ conn_tpc_begin(connectionObject *self, xidObject *xid) /* The transaction started ok, let's store this xid. */ Py_INCREF(xid); - self->tpc_xid = xid; + self->tpc_xid = (xidObject *)TO_STATE((PyObject *)xid); return 0; } diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c index ca61a7fd..fdd9b0ec 100644 --- a/psycopg/connection_type.c +++ b/psycopg/connection_type.c @@ -1337,13 +1337,13 @@ connection_setup(connectionObject *self, const char *dsn, long int async) ); if (0 > psycopg_strdup(&self->dsn, dsn, -1)) { goto exit; } - if (!(self->notice_list = PyList_New(0))) { goto exit; } - if (!(self->notifies = PyList_New(0))) { goto exit; } + if (!(self->notice_list = TO_STATE(PyList_New(0)))) { goto exit; } + if (!(self->notifies = TO_STATE(PyList_New(0)))) { goto exit; } self->async = async; self->status = CONN_STATUS_SETUP; self->async_status = ASYNC_DONE; - if (!(self->string_types = PyDict_New())) { goto exit; } - if (!(self->binary_types = PyDict_New())) { goto exit; } + if (!(self->string_types = TO_STATE(PyDict_New()))) { goto exit; } + if (!(self->binary_types = TO_STATE(PyDict_New()))) { goto exit; } self->isolevel = ISOLATION_LEVEL_DEFAULT; self->readonly = STATE_DEFAULT; self->deferrable = STATE_DEFAULT; diff --git a/psycopg/utils.c b/psycopg/utils.c index 81171bdc..01ddf570 100644 --- a/psycopg/utils.c +++ b/psycopg/utils.c @@ -465,3 +465,19 @@ psyco_GetDecimalType(void) return decimalType; } + + +/* Transfer ownership of an object to another object's state. + * + * Work around what seems a bug to the cpychecker which doesn't recognise + * the new reference: tell it one reference is just gone. + * + * See davidmalcolm/gcc-python-plugin#109 + */ +#ifdef WITH_CPYCHECKER_RETURNS_BORROWED_REF_ATTRIBUTE +STEALS(1) IGNORE_REFCOUNT BORROWED PyObject * +TO_STATE(PyObject* obj) +{ + return obj; +} +#endif diff --git a/psycopg/utils.h b/psycopg/utils.h index 3855cd86..0aa5a10d 100644 --- a/psycopg/utils.h +++ b/psycopg/utils.h @@ -58,4 +58,10 @@ HIDDEN RAISES BORROWED PyObject *psyco_set_error( HIDDEN PyObject *psyco_GetDecimalType(void); +#ifdef WITH_CPYCHECKER_RETURNS_BORROWED_REF_ATTRIBUTE +HIDDEN STEALS(1) IGNORE_REFCOUNT BORROWED PyObject *TO_STATE(PyObject* obj); +#else +#define TO_STATE(x) x +#endif + #endif /* !defined(UTILS_H) */