Commit 505e90f9 authored by Yu Feng's avatar Yu Feng Committed by GitHub

Use std::move in c++ during yield context switch. (GH-4154)

When compiling pyarrow with cython 3.0 we get an error about the copy constructor of an object has been deleted on the generated context switch code.

Also make the "cpp_temp_assignment" test only run in C++11 since it is based on `std::move()`.
parent 9b98c4b8
......@@ -9898,7 +9898,12 @@ class YieldExprNode(ExprNode):
for cname, type, manage_ref in code.funcstate.temps_in_use():
save_cname = code.funcstate.closure_temps.allocate_temp(type)
saved.append((cname, save_cname, type))
code.put_xgiveref(cname, type)
if type.is_cpp_class:
code.globalstate.use_utility_code(
UtilityCode.load_cached("MoveIfSupported", "CppSupport.cpp"))
cname = "__PYX_STD_MOVE_IF_SUPPORTED(%s)" % cname
else:
code.put_xgiveref(cname, type)
code.putln('%s->%s = %s;' % (Naming.cur_scope_cname, save_cname, cname))
code.put_xgiveref(Naming.retval_cname, py_object_type)
......@@ -9929,9 +9934,12 @@ class YieldExprNode(ExprNode):
code.put_label(label_name)
for cname, save_cname, type in saved:
code.putln('%s = %s->%s;' % (cname, Naming.cur_scope_cname, save_cname))
save_cname = "%s->%s" % (Naming.cur_scope_cname, save_cname)
if type.is_cpp_class:
save_cname = "__PYX_STD_MOVE_IF_SUPPORTED(%s)" % save_cname
code.putln('%s = %s;' % (cname, save_cname))
if type.is_pyobject:
code.putln('%s->%s = 0;' % (Naming.cur_scope_cname, save_cname))
code.putln('%s = 0;' % save_cname)
code.put_xgotref(cname, type)
self.generate_sent_value_handling_code(code, Naming.sent_value_cname)
if self.result_is_used:
......
......@@ -2089,7 +2089,7 @@ def main():
args.append(arg)
from optparse import OptionParser
parser = OptionParser()
parser = OptionParser(usage="usage: %prog [options] [selector ...]")
parser.add_option("--no-cleanup", dest="cleanup_workdir",
action="store_false", default=True,
help="do not delete the generated C files (allows passing --no-cython on next run)")
......
# tag: cpp
# tag: cpp,cpp11
# mode: compile
cdef extern from *:
"""
#if __cplusplus >= 201103L
class NoAssignIterator {
public:
explicit NoAssignIterator(int pos) : pos_(pos) {}
NoAssignIterator(NoAssignIterator&) = delete;
NoAssignIterator(NoAssignIterator&&) {}
NoAssignIterator& operator=(NoAssignIterator&) = delete;
NoAssignIterator& operator=(NoAssignIterator&&) { return *this; }
// Default constructor of temp variable is needed by Cython
// as of 3.0a6.
NoAssignIterator() : pos_(0) {}
int operator*() {
return pos_;
}
NoAssignIterator operator++() {
return NoAssignIterator(pos_ + 1);
}
int operator!=(NoAssignIterator other) {
return pos_ != other.pos_;
}
int pos_;
};
class NoAssign {
public:
NoAssign() {}
......@@ -12,15 +32,13 @@ cdef extern from *:
NoAssign& operator=(NoAssign&) = delete;
NoAssign& operator=(NoAssign&&) { return *this; }
void func() {}
NoAssignIterator begin() {
return NoAssignIterator(0);
}
NoAssignIterator end() {
return NoAssignIterator(2);
}
};
#else
// the test becomes meaningless
// (but just declare something to ensure it passes)
class NoAssign {
public:
void func() {}
};
#endif
NoAssign get_NoAssign_Py() {
return NoAssign();
......@@ -28,9 +46,17 @@ cdef extern from *:
NoAssign get_NoAssign_Cpp() {
return NoAssign();
}
"""
cdef cppclass NoAssignIterator:
int operator*()
NoAssignIterator operator++()
int operator!=(NoAssignIterator)
cdef cppclass NoAssign:
void func()
NoAssignIterator begin()
NoAssignIterator end()
# might raise Python exception (thus needs a temp)
NoAssign get_NoAssign_Py() except *
......@@ -63,3 +89,7 @@ cdef class AssignToClassAttr:
def __init__(self):
self.attr = get_NoAssign_Py()
self.attr = get_NoAssign_Cpp()
def test_generator_cpp_iterator_as_temp():
for i in get_NoAssign_Py():
yield i
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