Skip to content

Commit

Permalink
Add exception handling to signature of make_unique() (GH-5569)
Browse files Browse the repository at this point in the history
Also tweak the selection for move-if-supported by adding a feature flag `CYTHON_USE_CPP_STD_MOVE`.
This now lets the user enable it even if the compiler support isn't
detected. This is useful because the new signature for `make_unique()`
kind of relies on move-if-supported to work.

Fixes #5560
  • Loading branch information
da-woods committed Jul 31, 2023
1 parent 292c72c commit 365ba8e
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 6 deletions.
3 changes: 1 addition & 2 deletions Cython/Includes/libcpp/memory.pxd
Expand Up @@ -106,8 +106,7 @@ cdef extern from "<memory>" namespace "std" nogil:
# Smart pointer non-member operations
shared_ptr[T] make_shared[T](...) except +

# Temporaries used for exception handling break generated code
unique_ptr[T] make_unique[T](...) # except +
unique_ptr[T] make_unique[T](...) except +

# No checking on the compatibility of T and U.
cdef shared_ptr[T] static_pointer_cast[T, U](const shared_ptr[U]&)
Expand Down
3 changes: 1 addition & 2 deletions Cython/Utility/CppSupport.cpp
Expand Up @@ -61,8 +61,7 @@ auto __Pyx_pythran_to_python(T &&value) -> decltype(to_python(

////////////// MoveIfSupported.proto //////////////////

#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
// move should be defined for these versions of MSVC, but __cplusplus isn't set usefully
#if CYTHON_USE_CPP_STD_MOVE
#include <utility>
#define __PYX_STD_MOVE_IF_SUPPORTED(x) std::move(x)
#else
Expand Down
10 changes: 10 additions & 0 deletions Cython/Utility/ModuleSetupCode.c
Expand Up @@ -479,6 +479,16 @@
# endif
#endif

#ifndef CYTHON_USE_CPP_STD_MOVE
// msvc doesn't set __cplusplus to a useful value
#if defined(__cplusplus) && ( \
__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600))
#define CYTHON_USE_CPP_STD_MOVE 1
#else
#define CYTHON_USE_CPP_STD_MOVE 0
#endif
#endif

#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None)

#ifdef _MSC_VER
Expand Down
17 changes: 15 additions & 2 deletions tests/run/cpp_smart_ptr.pyx
@@ -1,7 +1,7 @@
# mode: run
# tag: cpp, werror, cpp11, no-cpp-locals
# tag: cpp, werror, cpp14, no-cpp-locals

from libcpp.memory cimport unique_ptr, shared_ptr, default_delete, dynamic_pointer_cast
from libcpp.memory cimport unique_ptr, shared_ptr, default_delete, dynamic_pointer_cast, make_unique
from libcpp cimport nullptr

cdef extern from "cpp_smart_ptr_helper.h":
Expand All @@ -11,6 +11,9 @@ cdef extern from "cpp_smart_ptr_helper.h":
cdef cppclass FreePtr[T]:
pass

cdef cppclass RaiseOnConstruct:
pass


ctypedef const CountAllocDealloc const_CountAllocDealloc

Expand Down Expand Up @@ -45,6 +48,16 @@ def test_unique_ptr():
x_ptr3.reset()
assert x_ptr3.get() == nullptr;

# Test that make_unique works
cdef unique_ptr[int] x_ptr4
x_ptr4 = make_unique[int](5)
assert(x_ptr4) != nullptr
cdef unique_ptr[RaiseOnConstruct] x_ptr5
try:
x_ptr5 = make_unique[RaiseOnConstruct]()
except RuntimeError:
pass # good - this is what we expect


def test_const_shared_ptr():
"""
Expand Down
9 changes: 9 additions & 0 deletions tests/run/cpp_smart_ptr_helper.h
@@ -1,3 +1,5 @@
#include <stdexcept>

class CountAllocDealloc {
public:
CountAllocDealloc(int* alloc_count, int* dealloc_count)
Expand All @@ -22,3 +24,10 @@ struct FreePtr {
}
}
};

class RaiseOnConstruct {
public:
RaiseOnConstruct() {
throw std::runtime_error("Oh no!");
}
};

0 comments on commit 365ba8e

Please sign in to comment.