commit c24bedaed207837d233c2df9c011309fc63b6af6 Author: David Malcolm dmalcolm@redhat.com Date: Mon Sep 26 19:29:42 2011 -0400
cpychecker: assume that function pointers returning PyObject* work like constructors
Assume that a call through a function pointer that returns PyObject* either gives a new ref, or returns NULL and sets an exception
Update some of the function call machinery to avoid the need for the function to have a name
libcpychecker/absinterp.py | 18 +- libcpychecker/refcounts.py | 8 +- .../refcounts/object_from_callback/input.c | 80 +++ .../refcounts/object_from_callback/script.py | 22 + .../refcounts/object_from_callback/stdout.txt | 626 ++++++++++++++++++++ 5 files changed, 747 insertions(+), 7 deletions(-) --- diff --git a/libcpychecker/absinterp.py b/libcpychecker/absinterp.py index 4e8d66f..b6ea626 100644 --- a/libcpychecker/absinterp.py +++ b/libcpychecker/absinterp.py @@ -72,6 +72,14 @@ class AbstractValue: check_isinstance(state, State) check_isinstance(stmt, gcc.GimpleCall) returntype = stmt.fn.type.dereference.type + + if str(returntype) == 'struct PyObject *': + log('Invocation of function pointer returning PyObject *') + # Assume that all such functions either: + # - return a new reference, or + # - return NULL and set an exception (e.g. MemoryError) + return state.cpython.make_transitions_for_new_ref_or_fail(stmt, + 'new ref from call through function pointer') return [state.mktrans_assignment(stmt.lhs, UnknownValue(returntype, stmt.loc), 'calling %s' % self)] @@ -1166,10 +1174,14 @@ class State: check_isinstance(s_success, State) check_isinstance(s_failure, State)
- fnname = stmt.fn.operand.name + if hasattr(stmt.fn, 'operand'): + fnname = stmt.fn.operand.name + return [Transition(self, s_success, '%s() succeeds' % fnname), + Transition(self, s_failure, '%s() fails' % fnname)] + else: + return [Transition(self, s_success, 'call succeeds'), + Transition(self, s_failure, 'call fails')]
- return [Transition(self, s_success, '%s() succeeds' % fnname), - Transition(self, s_failure, '%s() fails' % fnname)]
def eval_stmt_args(self, stmt): check_isinstance(stmt, gcc.GimpleCall) diff --git a/libcpychecker/refcounts.py b/libcpychecker/refcounts.py index 5132e7f..06caac2 100644 --- a/libcpychecker/refcounts.py +++ b/libcpychecker/refcounts.py @@ -444,7 +444,7 @@ class CPython(Facet): stmt.loc) return newstate
- def mkstate_exception(self, stmt, fnname): + def mkstate_exception(self, stmt): """Make a new State, giving NULL and some exception""" if stmt.lhs: value = ConcreteValue(stmt.lhs.type, stmt.loc, 0) @@ -465,11 +465,11 @@ class CPython(Facet): Optionally, a name for the new object can be supplied; otherwise a sane default will be used. """ - fnname = stmt.fn.operand.name if objname is None: + fnname = stmt.fn.operand.name objname = 'new ref from call to %s' % fnname s_success, nonnull = self.mkstate_new_ref(stmt, objname) - s_failure = self.mkstate_exception(stmt, fnname) + s_failure = self.mkstate_exception(stmt) return self.state.make_transitions_for_fncall(stmt, s_success, s_failure)
def object_ptr_has_global_ob_type(self, v_object_ptr, vardecl_name): @@ -909,7 +909,7 @@ class CPython(Facet): # #define Py_InitModule4 Py_InitModule4TraceRefs_64 # #define Py_InitModule4 Py_InitModule4TraceRefs s_success = self.mkstate_borrowed_ref(stmt, 'output from Py_InitModule4') - s_failure = self.mkstate_exception(stmt, 'Py_InitModule4') + s_failure = self.mkstate_exception(stmt) return self.state.make_transitions_for_fncall(stmt, s_success, s_failure)
######################################################################## diff --git a/tests/cpychecker/refcounts/object_from_callback/input.c b/tests/cpychecker/refcounts/object_from_callback/input.c new file mode 100644 index 0000000..830ecb5 --- /dev/null +++ b/tests/cpychecker/refcounts/object_from_callback/input.c @@ -0,0 +1,80 @@ +/* + Copyright 2011 David Malcolm dmalcolm@redhat.com + Copyright 2011 Red Hat, Inc. + + This is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see + http://www.gnu.org/licenses/. +*/ + +#include <Python.h> + +/* + Test of correct reference-handling when dealing with a callback that + constructs an object +*/ + +PyObject * +test(PyObject *(*ctor)(void)) +{ + PyObject *dict = NULL; + PyObject *key = NULL; + PyObject *value = NULL; + + dict = PyDict_New(); + if (!dict) { + goto error; + } + + key = PyLong_FromLong(500); + if (!key) { + goto error; + } + + /* + Invoke the callback; the checker will assume that it follows normal + object ownership rules: + */ + value = (*ctor)(); + if (!value) { + /* should have set an exception */ + goto error; + } + + if (-1 == PyDict_SetItem(dict, key, value)) { + goto error; + } + /* + The successful call added refs on both "key" and "value", owned by the + dictionary. + We must now drop our references on them: + */ + Py_DECREF(key); + Py_DECREF(value); + + return dict; + + error: + Py_XDECREF(dict); + Py_XDECREF(key); + Py_XDECREF(value); + return NULL; +} + +/* + PEP-7 +Local variables: +c-basic-offset: 4 +indent-tabs-mode: nil +End: +*/ diff --git a/tests/cpychecker/refcounts/object_from_callback/script.py b/tests/cpychecker/refcounts/object_from_callback/script.py new file mode 100644 index 0000000..fdd5ba3 --- /dev/null +++ b/tests/cpychecker/refcounts/object_from_callback/script.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2011 David Malcolm dmalcolm@redhat.com +# Copyright 2011 Red Hat, Inc. +# +# This is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# http://www.gnu.org/licenses/. + +from libcpychecker import main +main(verify_refcounting=True, + dump_traces=True, + show_traces=False) diff --git a/tests/cpychecker/refcounts/object_from_callback/stdout.txt b/tests/cpychecker/refcounts/object_from_callback/stdout.txt new file mode 100644 index 0000000..a7ed67d --- /dev/null +++ b/tests/cpychecker/refcounts/object_from_callback/stdout.txt @@ -0,0 +1,626 @@ +Trace 0: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call succeeds' + 'taking False path' + 'PyDict_SetItem() succeeds' + 'taking False path' + 'taking True path' + 'taking True path' + 'returning' + Return value: + repr(): PointerToRegion(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34))) + str(): (struct PyObject *)&RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) from tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: refs: 1 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionForGlobal(gcc.VarDecl('PyDict_Type'))) + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39), region=RegionForGlobal(gcc.VarDecl('PyLong_Type'))) + new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48: + repr(): RegionOnHeap('new ref from call through function pointer', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48)) + str(): new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48 + r->ob_refcnt: refs: 0 + N where N >= 1 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48), region=Region('PyTypeObject for new ref from call through function pointer')) + Exception: + (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:29 + +Trace 1: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call succeeds' + 'taking False path' + 'PyDict_SetItem() succeeds' + 'taking False path' + 'taking True path' + 'taking False path' + 'calling tp_dealloc on new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48' + 'returning' + Return value: + repr(): PointerToRegion(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34))) + str(): (struct PyObject *)&RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) from tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: refs: 1 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionForGlobal(gcc.VarDecl('PyDict_Type'))) + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39), region=RegionForGlobal(gcc.VarDecl('PyLong_Type'))) + new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48: + repr(): RegionOnHeap('new ref from call through function pointer', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48)) + str(): new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48 + r->ob_refcnt: None + r->ob_type: None + Exception: + (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:29 + +Trace 2: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call succeeds' + 'taking False path' + 'PyDict_SetItem() succeeds' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39' + 'taking True path' + 'returning' + Return value: + repr(): PointerToRegion(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34))) + str(): (struct PyObject *)&RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) from tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: refs: 1 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionForGlobal(gcc.VarDecl('PyDict_Type'))) + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: None + r->ob_type: None + new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48: + repr(): RegionOnHeap('new ref from call through function pointer', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48)) + str(): new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48 + r->ob_refcnt: refs: 0 + N where N >= 1 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48), region=Region('PyTypeObject for new ref from call through function pointer')) + Exception: + (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:29 + +Trace 3: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call succeeds' + 'taking False path' + 'PyDict_SetItem() succeeds' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39' + 'taking False path' + 'calling tp_dealloc on new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48' + 'returning' + Return value: + repr(): PointerToRegion(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34))) + str(): (struct PyObject *)&RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) from tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: refs: 1 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionForGlobal(gcc.VarDecl('PyDict_Type'))) + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: None + r->ob_type: None + new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48: + repr(): RegionOnHeap('new ref from call through function pointer', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48)) + str(): new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48 + r->ob_refcnt: None + r->ob_type: None + Exception: + (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:29 + +Trace 4: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call succeeds' + 'taking False path' + 'PyDict_SetItem() fails' + 'taking True path' + 'taking False path' + 'taking True path' + 'taking False path' + 'taking True path' + 'taking False path' + 'taking True path' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34: + repr(): RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) + str(): PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionForGlobal(gcc.VarDecl('PyDict_Type'))) + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39), region=RegionForGlobal(gcc.VarDecl('PyLong_Type'))) + new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48: + repr(): RegionOnHeap('new ref from call through function pointer', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48)) + str(): new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48), region=Region('PyTypeObject for new ref from call through function pointer')) + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:54 + +Trace 5: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call succeeds' + 'taking False path' + 'PyDict_SetItem() fails' + 'taking True path' + 'taking False path' + 'taking True path' + 'taking False path' + 'taking True path' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34: + repr(): RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) + str(): PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionForGlobal(gcc.VarDecl('PyDict_Type'))) + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39), region=RegionForGlobal(gcc.VarDecl('PyLong_Type'))) + new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48: + repr(): RegionOnHeap('new ref from call through function pointer', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48)) + str(): new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48 + r->ob_refcnt: None + r->ob_type: None + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:54 + +Trace 6: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call succeeds' + 'taking False path' + 'PyDict_SetItem() fails' + 'taking True path' + 'taking False path' + 'taking True path' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39' + 'taking False path' + 'taking True path' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34: + repr(): RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) + str(): PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionForGlobal(gcc.VarDecl('PyDict_Type'))) + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: None + r->ob_type: None + new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48: + repr(): RegionOnHeap('new ref from call through function pointer', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48)) + str(): new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48), region=Region('PyTypeObject for new ref from call through function pointer')) + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:54 + +Trace 7: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call succeeds' + 'taking False path' + 'PyDict_SetItem() fails' + 'taking True path' + 'taking False path' + 'taking True path' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34: + repr(): RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) + str(): PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionForGlobal(gcc.VarDecl('PyDict_Type'))) + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: None + r->ob_type: None + new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48: + repr(): RegionOnHeap('new ref from call through function pointer', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48)) + str(): new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48 + r->ob_refcnt: None + r->ob_type: None + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:54 + +Trace 8: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call succeeds' + 'taking False path' + 'PyDict_SetItem() fails' + 'taking True path' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34' + 'taking False path' + 'taking True path' + 'taking False path' + 'taking True path' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34: + repr(): RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) + str(): PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: None + r->ob_type: None + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39), region=RegionForGlobal(gcc.VarDecl('PyLong_Type'))) + new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48: + repr(): RegionOnHeap('new ref from call through function pointer', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48)) + str(): new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48), region=Region('PyTypeObject for new ref from call through function pointer')) + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:54 + +Trace 9: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call succeeds' + 'taking False path' + 'PyDict_SetItem() fails' + 'taking True path' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34' + 'taking False path' + 'taking True path' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34: + repr(): RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) + str(): PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: None + r->ob_type: None + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39), region=RegionForGlobal(gcc.VarDecl('PyLong_Type'))) + new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48: + repr(): RegionOnHeap('new ref from call through function pointer', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48)) + str(): new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48 + r->ob_refcnt: None + r->ob_type: None + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:54 + +Trace 10: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call succeeds' + 'taking False path' + 'PyDict_SetItem() fails' + 'taking True path' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39' + 'taking False path' + 'taking True path' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34: + repr(): RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) + str(): PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: None + r->ob_type: None + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: None + r->ob_type: None + new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48: + repr(): RegionOnHeap('new ref from call through function pointer', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48)) + str(): new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48), region=Region('PyTypeObject for new ref from call through function pointer')) + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:54 + +Trace 11: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call succeeds' + 'taking False path' + 'PyDict_SetItem() fails' + 'taking True path' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34: + repr(): RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) + str(): PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: None + r->ob_type: None + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: None + r->ob_type: None + new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48: + repr(): RegionOnHeap('new ref from call through function pointer', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=48)) + str(): new ref from call through function pointer allocated at tests/cpychecker/refcounts/object_from_callback/input.c:48 + r->ob_refcnt: None + r->ob_type: None + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:54 + +Trace 12: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call fails' + 'taking True path' + 'taking False path' + 'taking True path' + 'taking False path' + 'taking True path' + 'taking True path' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34: + repr(): RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) + str(): PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionForGlobal(gcc.VarDecl('PyDict_Type'))) + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39), region=RegionForGlobal(gcc.VarDecl('PyLong_Type'))) + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:48 + +Trace 13: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call fails' + 'taking True path' + 'taking False path' + 'taking True path' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39' + 'taking True path' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34: + repr(): RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) + str(): PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionForGlobal(gcc.VarDecl('PyDict_Type'))) + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: None + r->ob_type: None + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:48 + +Trace 14: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call fails' + 'taking True path' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34' + 'taking False path' + 'taking True path' + 'taking True path' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34: + repr(): RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) + str(): PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: None + r->ob_type: None + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39), region=RegionForGlobal(gcc.VarDecl('PyLong_Type'))) + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:48 + +Trace 15: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() succeeds' + 'taking False path' + 'call fails' + 'taking True path' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39' + 'taking True path' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34: + repr(): RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) + str(): PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: None + r->ob_type: None + PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39: + repr(): RegionOnHeap('PyLongObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=39)) + str(): PyLongObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:39 + r->ob_refcnt: None + r->ob_type: None + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:48 + +Trace 16: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() fails' + 'taking True path' + 'taking False path' + 'taking True path' + 'taking True path' + 'taking True path' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34: + repr(): RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) + str(): PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: refs: 0 + N where N >= 0 + r->ob_type: PointerToRegion(gcctype='struct PyTypeObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34), region=RegionForGlobal(gcc.VarDecl('PyDict_Type'))) + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:39 + +Trace 17: + Transitions: + 'PyDict_New() succeeds' + 'taking False path' + 'PyLong_FromLong() fails' + 'taking True path' + 'taking False path' + 'taking False path' + 'calling tp_dealloc on PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34' + 'taking True path' + 'taking True path' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34: + repr(): RegionOnHeap('PyDictObject', gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=34)) + str(): PyDictObject allocated at tests/cpychecker/refcounts/object_from_callback/input.c:34 + r->ob_refcnt: None + r->ob_type: None + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:39 + +Trace 18: + Transitions: + 'PyDict_New() fails' + 'taking True path' + 'taking True path' + 'taking True path' + 'taking True path' + 'returning' + Return value: + repr(): ConcreteValue(gcctype='struct PyObject *', loc=gcc.Location(file='tests/cpychecker/refcounts/object_from_callback/input.c', line=71), value=0) + str(): (struct PyObject *)0 from tests/cpychecker/refcounts/object_from_callback/input.c:71 + Exception: + (struct PyObject *)&RegionForGlobal(gcc.VarDecl('PyExc_MemoryError')) from tests/cpychecker/refcounts/object_from_callback/input.c:34
gcc-python-plugin-commits@lists.stg.fedorahosted.org