From 365ba8efb1945c02fa8c231dacef14b6c6482502 Mon Sep 17 00:00:00 2001 From: da-woods Date: Mon, 31 Jul 2023 11:18:33 +0100 Subject: [PATCH] Add exception handling to signature of make_unique() (GH-5569) 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 https://github.com/cython/cython/issues/5560 --- Cython/Includes/libcpp/memory.pxd | 3 +-- Cython/Utility/CppSupport.cpp | 3 +-- Cython/Utility/ModuleSetupCode.c | 10 ++++++++++ tests/run/cpp_smart_ptr.pyx | 17 +++++++++++++++-- tests/run/cpp_smart_ptr_helper.h | 9 +++++++++ 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/Cython/Includes/libcpp/memory.pxd b/Cython/Includes/libcpp/memory.pxd index c477c93fead..0b2070f429a 100644 --- a/Cython/Includes/libcpp/memory.pxd +++ b/Cython/Includes/libcpp/memory.pxd @@ -106,8 +106,7 @@ cdef extern from "" 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]&) diff --git a/Cython/Utility/CppSupport.cpp b/Cython/Utility/CppSupport.cpp index ba0002c94fc..60068c2ca55 100644 --- a/Cython/Utility/CppSupport.cpp +++ b/Cython/Utility/CppSupport.cpp @@ -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 #define __PYX_STD_MOVE_IF_SUPPORTED(x) std::move(x) #else diff --git a/Cython/Utility/ModuleSetupCode.c b/Cython/Utility/ModuleSetupCode.c index 82008a1e252..3227ba291bd 100644 --- a/Cython/Utility/ModuleSetupCode.c +++ b/Cython/Utility/ModuleSetupCode.c @@ -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 diff --git a/tests/run/cpp_smart_ptr.pyx b/tests/run/cpp_smart_ptr.pyx index d71151c5e39..41d31c75e14 100644 --- a/tests/run/cpp_smart_ptr.pyx +++ b/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": @@ -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 @@ -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(): """ diff --git a/tests/run/cpp_smart_ptr_helper.h b/tests/run/cpp_smart_ptr_helper.h index 02d73868cd7..c291957339c 100644 --- a/tests/run/cpp_smart_ptr_helper.h +++ b/tests/run/cpp_smart_ptr_helper.h @@ -1,3 +1,5 @@ +#include + class CountAllocDealloc { public: CountAllocDealloc(int* alloc_count, int* dealloc_count) @@ -22,3 +24,10 @@ struct FreePtr { } } }; + +class RaiseOnConstruct { + public: + RaiseOnConstruct() { + throw std::runtime_error("Oh no!"); + } +};