Commit e44c12e4 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Make bind_obj_out borrowed

Looked at all places it comes from and this looks safe
(it's alive at least as long as the other arguments).

We are now crashing on cpython_oldstyle_getattr_crash (a CPython crasher)
but that's not really the fault of this change.
parent 2c916cb1
......@@ -872,7 +872,7 @@ static PyObject* call_attribute(PyObject* self, PyObject* attr, PyObject* name)
template <ExceptionStyle S, Rewritable rewritable>
Box* slotTpGetattrHookInternal(Box* self, BoxedString* name, GetattrRewriteArgs* rewrite_args, bool for_call,
Box** bind_obj_out, RewriterVar** r_bind_obj_out) noexcept(S == CAPI) {
BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out) noexcept(S == CAPI) {
if (rewritable == NOT_REWRITABLE) {
assert(!rewrite_args);
rewrite_args = NULL;
......
......@@ -58,7 +58,7 @@ int compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, const ch
class GetattrRewriteArgs;
template <ExceptionStyle S, Rewritable rewritable>
Box* slotTpGetattrHookInternal(Box* self, BoxedString* attr, GetattrRewriteArgs* rewrite_args, bool for_call,
Box** bind_obj_out, RewriterVar** r_bind_obj_out) noexcept(S == CAPI);
BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out) noexcept(S == CAPI);
}
#endif
......@@ -1807,7 +1807,7 @@ bool isNondataDescriptorInstanceSpecialCase(Box* descr) {
template <Rewritable rewritable>
Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box* obj, Box* descr, RewriterVar* r_descr,
bool for_call, Box** bind_obj_out, RewriterVar** r_bind_obj_out) {
bool for_call, BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out) {
if (rewritable == NOT_REWRITABLE) {
assert(!rewrite_args);
rewrite_args = NULL;
......@@ -1888,7 +1888,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
}
return boxInstanceMethod(im_self, im_func, im_class);
} else {
*bind_obj_out = incref(im_self);
*bind_obj_out = im_self;
if (rewrite_args) {
rewrite_args->setReturn(r_im_func, ReturnConvention::HAS_RETURN);
*r_bind_obj_out = r_im_self;
......@@ -1915,7 +1915,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
rewrite_args->setReturn(r_descr, ReturnConvention::HAS_RETURN);
*r_bind_obj_out = rewrite_args->obj;
}
*bind_obj_out = incref(obj);
*bind_obj_out = obj;
return incref(descr);
} else {
BoxedWrapperDescriptor* self = static_cast<BoxedWrapperDescriptor*>(descr);
......@@ -1944,7 +1944,7 @@ Box* nondataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, Box
// r_descr must represent a valid object.
template <Rewritable rewritable>
Box* descriptorClsSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedClass* cls, Box* descr, RewriterVar* r_descr,
bool for_call, Box** bind_obj_out, RewriterVar** r_bind_obj_out) {
bool for_call, BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out) {
if (rewritable == NOT_REWRITABLE) {
assert(!rewrite_args);
rewrite_args = NULL;
......@@ -1999,7 +1999,7 @@ Box* boxChar(char c) {
// r_descr needs to represent a valid object
template <Rewritable rewritable>
Box* dataDescriptorInstanceSpecialCases(GetattrRewriteArgs* rewrite_args, BoxedString* attr_name, Box* obj, Box* descr,
RewriterVar* r_descr, bool for_call, Box** bind_obj_out,
RewriterVar* r_descr, bool for_call, BORROWED(Box**) bind_obj_out,
RewriterVar** r_bind_obj_out) {
if (rewritable == NOT_REWRITABLE) {
assert(!rewrite_args);
......@@ -2214,7 +2214,7 @@ static void ensureValidCapiReturn(Box* r) {
template <ExceptionStyle S, Rewritable rewritable>
Box* getattrInternalEx(Box* obj, BoxedString* attr, GetattrRewriteArgs* rewrite_args, bool cls_only, bool for_call,
Box** bind_obj_out, RewriterVar** r_bind_obj_out) noexcept(S == CAPI) {
BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out) noexcept(S == CAPI) {
if (rewritable == NOT_REWRITABLE) {
assert(!rewrite_args);
rewrite_args = NULL;
......@@ -2431,7 +2431,7 @@ Box* processDescriptor(Box* obj, Box* inst, Box* owner) {
template <bool IsType, Rewritable rewritable>
Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rewrite_args, bool cls_only, bool for_call,
Box** bind_obj_out, RewriterVar** r_bind_obj_out) {
BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out) {
if (rewritable == NOT_REWRITABLE) {
assert(!rewrite_args);
rewrite_args = NULL;
......@@ -3745,8 +3745,6 @@ Box* callattrInternal(Box* obj, BoxedString* attr, LookupScope scope, CallattrRe
return val;
}
AUTO_XDECREF(bind_obj);
if (bind_obj != NULL) {
Box** new_args = NULL;
if (npassed_args >= 3) {
......
......@@ -168,7 +168,7 @@ template <ExceptionStyle S> inline Box* getattrInternal(Box* obj, BoxedString* a
// __getattribute__.
template <bool IsType, Rewritable rewritable>
Box* getattrInternalGeneric(Box* obj, BoxedString* attr, GetattrRewriteArgs* rewrite_args, bool cls_only, bool for_call,
Box** bind_obj_out, RewriterVar** r_bind_obj_out);
BORROWED(Box**) bind_obj_out, RewriterVar** r_bind_obj_out);
extern "C" PyObject* type_getattro(PyObject* o, PyObject* name) noexcept;
......
# skip-if: '-n' in EXTRA_JIT_ARGS or '-O' in EXTRA_JIT_ARGS
# Tests to see if we add any extra refs to function arguments.
import sys
......@@ -7,4 +8,13 @@ def f(o):
print sys.getrefcount(o)
# This gives 3 for CPython and our interpreter, but 2 for the llvm tier:
# f(object())
f(object())
import sys
class C(object):
def foo(self, *args):
print sys.getrefcount(self)
c = C()
a = (c.foo)
print sys.getrefcount(c)
c.foo()
# skip-if: True
# - sadly, we have now inherited CPython's buggy behavior here
# This segfaults under python-dbg
# (In a release build it "works" since the use-after-free happens without penalty.)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment