Commit 3c2d60a1 authored by Xavier Thompson's avatar Xavier Thompson

Fix reference counting in 'consume' operations

parent 5ea4b23c
...@@ -11410,10 +11410,9 @@ class ConsumeNode(ExprNode): ...@@ -11410,10 +11410,9 @@ class ConsumeNode(ExprNode):
self.generate_runtime_check = True self.generate_runtime_check = True
self.type = PyrexTypes.cyp_class_qualified_type(operand_type, 'iso~') self.type = PyrexTypes.cyp_class_qualified_type(operand_type, 'iso~')
self.operand_is_named = self.operand.is_name or self.operand.is_attribute self.operand_is_named = self.operand.is_name or self.operand.is_attribute
self.is_temp = self.operand_is_named or self.generate_runtime_check self.is_temp = self.operand_is_named or (self.generate_runtime_check and not self.operand.is_temp)
if self.is_temp: if not self.operand_is_named and not self.generate_runtime_check:
# We steal the reference of the operand. return self.operand
self.use_managed_ref = False
return self return self
def may_be_none(self): def may_be_none(self):
...@@ -11429,30 +11428,32 @@ class ConsumeNode(ExprNode): ...@@ -11429,30 +11428,32 @@ class ConsumeNode(ExprNode):
def calculate_result_code(self): def calculate_result_code(self):
return self.operand.result() return self.operand.result()
def result_in_temp(self):
return self.is_temp or self.operand.result_in_temp()
def generate_result_code(self, code): def generate_result_code(self, code):
result_code = self.result()
if self.is_temp: if self.is_temp:
operand_result = self.operand.result() code.putln("%s = %s;" % (result_code, self.operand.result()))
result_code = self.result() if self.generate_runtime_check:
code.putln("%s = %s;" % (result_code, operand_result)) code.putln("if (%s != NULL && !%s->CyObject_iso()) {" % (result_code, result_code))
if self.generate_runtime_check: if self.nogil:
code.putln("if (%s != NULL && !%s->CyObject_iso()) {" % (result_code, result_code)) code.putln("#ifdef WITH_THREAD")
if self.nogil: code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
code.putln("#ifdef WITH_THREAD") code.putln("#endif")
code.putln("PyGILState_STATE _save = PyGILState_Ensure();") code.putln("PyErr_SetString(PyExc_TypeError, \"'consume' operand is not isolated\");")
code.putln("#endif") if self.nogil:
code.putln("PyErr_SetString(PyExc_TypeError, \"'consume' operand is not isolated\");") code.putln("#ifdef WITH_THREAD")
if self.nogil: code.putln("PyGILState_Release(_save);")
code.putln("#ifdef WITH_THREAD") code.putln("#endif")
code.putln("PyGILState_Release(_save);") code.putln(
code.putln("#endif") code.error_goto(self.pos))
code.putln( code.putln("}")
code.error_goto(self.pos)) if self.operand_is_named:
code.putln("}") code.putln("%s = NULL;" % self.operand.result())
# We steal the reference of the operand.
code.putln("%s = NULL;" % operand_result) def generate_post_assignment_code(self, code):
if self.operand.is_temp: self.operand.generate_post_assignment_code(code)
# TODO: steal the reference of the operand instead
code.put_incref(self.result(), self.type)
class TypeidNode(ExprNode): class TypeidNode(ExprNode):
......
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