diff options
author | Zachary Turner <zturner@google.com> | 2015-10-13 18:16:15 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2015-10-13 18:16:15 +0000 |
commit | f8b22f8fea181d2564267282e6c8249fde01bc13 (patch) | |
tree | e3c0f7f4bcb19037d37fe1821b9b06729ca773e9 /llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp | |
parent | af0159bafb29d0651d7092cce69b2e248e664a65 (diff) | |
download | bcm5719-llvm-f8b22f8fea181d2564267282e6c8249fde01bc13.tar.gz bcm5719-llvm-f8b22f8fea181d2564267282e6c8249fde01bc13.zip |
Fix ref counting of Python objects.
PythonObjects were being incorrectly ref-counted. This problem was
pervasive throughout the codebase, leading to an unknown number of memory
leaks and potentially use-after-free.
The issue stems from the fact that Python native methods can either return
"borrowed" references or "owned" references. For the former category, you
*must* incref it prior to decrefing it. And for the latter category, you
should not incref it before decrefing it. This is mostly an issue when a
Python C API method returns a `PyObject` to you, but it can also happen with
a method accepts a `PyObject`. Notably, this happens in `PyList_SetItem`,
which is documented to "steal" the reference that you give it. So if you
pass something to `PyList_SetItem`, you cannot hold onto it unless you
incref it first. But since this is one of only two exceptions in the
entire API, it's confusing and difficult to remember.
Our `PythonObject` class was indiscriminantely increfing every object it
received, which means that if you passed it an owned reference, you now
have a dangling reference since owned references should not be increfed.
We were doing this in quite a few places.
There was also a fair amount of manual increfing and decrefing prevalent
throughout the codebase, which is easy to get wrong.
This patch solves the problem by making any construction of a
`PythonObject` from a `PyObject` take a flag which indicates whether it is
an owned reference or a borrowed reference. There is no way to construct a
`PythonObject` without this flag, and it does not offer a default value,
forcing the user to make an explicit decision every time.
All manual uses of `PyObject` have been cleaned up throughout the codebase
and replaced with `PythonObject` in order to make RAII the predominant
pattern when dealing with native Python objects.
Differential Revision: http://reviews.llvm.org/D13617
Reviewed By: Greg Clayton
llvm-svn: 250195
Diffstat (limited to 'llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp')
0 files changed, 0 insertions, 0 deletions