commit 52146cfed277aee3ea33fbd565bb39440aafa5c2
Author: David Malcolm <dmalcolm(a)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
Show replies by date