summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2015-10-13 18:16:15 +0000
committerZachary Turner <zturner@google.com>2015-10-13 18:16:15 +0000
commitf8b22f8fea181d2564267282e6c8249fde01bc13 (patch)
treee3c0f7f4bcb19037d37fe1821b9b06729ca773e9 /llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
parentaf0159bafb29d0651d7092cce69b2e248e664a65 (diff)
downloadbcm5719-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
OpenPOWER on IntegriCloud