commit 52146cfed277aee3ea33fbd565bb39440aafa5c2 Author: David Malcolm dmalcolm@redhat.com Date: Thu Mar 29 22:11:39 2012 -0400
implement GccCfgI_ForEachBlock; fix reference leak
gcc-python-cfg.c | 60 ++++++++++++++++++++++------------------ proposed-plugin-api/gcc-cfg.c | 17 +++++++++++- 2 files changed, 49 insertions(+), 28 deletions(-) --- diff --git a/gcc-python-cfg.c b/gcc-python-cfg.c index 8c67e4a..ea2caec 100644 --- a/gcc-python-cfg.c +++ b/gcc-python-cfg.c @@ -79,8 +79,11 @@ static bool add_edge_to_list(GccCfgEdgeI edge, void *user_data)
if (-1 == PyList_Append(result, item)) { Py_DECREF(item); + return true; }
+ /* Success: */ + Py_DECREF(item); return false; }
@@ -458,41 +461,44 @@ gcc_python_make_wrapper_basic_block(GccCfgBlockI bb) real_make_basic_block_wrapper); }
-/* - "struct control_flow_graph" is declared in basic-block.h, c.f.: - struct GTY(()) control_flow_graph { - ... snip ... - } -*/ +static bool add_block_to_list(GccCfgBlockI block, void *user_data) +{ + PyObject *result = (PyObject*)user_data; + PyObject *item; + + item = gcc_python_make_wrapper_basic_block(block); + if (!item) { + return true; + } + + if (-1 == PyList_Append(result, item)) { + Py_DECREF(item); + return true; + } + + /* Success: */ + Py_DECREF(item); + return false; +} + PyObject * gcc_Cfg_get_basic_blocks(PyGccCfg *self, void *closure) { - PyObject *result = NULL; - int i; + PyObject *result;
- result = PyList_New(self->cfg.inner->x_n_basic_blocks); + result = PyList_New(0); if (!result) { - goto error; - } - - for (i = 0; i < self->cfg.inner->x_n_basic_blocks; i++) { - PyObject *item; - item = gcc_python_make_wrapper_basic_block( - GccPrivate_make_CfgBlockI( - VEC_index(basic_block, - self->cfg.inner->x_basic_block_info, - i))); - if (!item) { - goto error; - } - PyList_SetItem(result, i, item); + return NULL; }
- return result; + if (GccCfgI_ForEachBlock(self->cfg, + add_block_to_list, + result)) { + Py_DECREF(result); + return NULL; + }
- error: - Py_XDECREF(result); - return NULL; + return result; }
extern PyTypeObject gcc_LabelDeclType; diff --git a/proposed-plugin-api/gcc-cfg.c b/proposed-plugin-api/gcc-cfg.c index 0ff948c..0a4caba 100644 --- a/proposed-plugin-api/gcc-cfg.c +++ b/proposed-plugin-api/gcc-cfg.c @@ -64,7 +64,22 @@ GccCfgI_GetExit(GccCfgI cfg) GCC_IMPLEMENT_PUBLIC_API(bool) GccCfgI_ForEachBlock(GccCfgI cfg, bool (*cb)(GccCfgBlockI block, void *user_data), - void *user_data); + void *user_data) +{ + int i; + + for (i = 0; i < cfg.inner->x_n_basic_blocks; i++) { + if (cb(GccPrivate_make_CfgBlockI( + VEC_index(basic_block, + cfg.inner->x_basic_block_info, + i)), + user_data)) { + return true; + } + } + return false; + +}
/*********************************************************** GccCfgBlockI
gcc-python-plugin-commits@lists.stg.fedorahosted.org