summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Schemenauer <nas-github@arctrix.com>2022-06-05 01:49:39 (GMT)
committerGitHub <noreply@github.com>2022-06-05 01:49:39 (GMT)
commit8bcc3fa3453e28511d04eaa0aa7d8e1a3495d518 (patch)
treecd378fd5df0961d632fe18e195474404b3471d53
parent3d647e70cf4fd0e7cef68ed6662de3cb2cb0d63d (diff)
downloadcpython-8bcc3fa3453e28511d04eaa0aa7d8e1a3495d518.zip
cpython-8bcc3fa3453e28511d04eaa0aa7d8e1a3495d518.tar.gz
cpython-8bcc3fa3453e28511d04eaa0aa7d8e1a3495d518.tar.bz2
gh-93442: Make C++ version of _Py_CAST work with 0/NULL. (#93500)
Add C++ overloads for _Py_CAST_impl() to handle 0/NULL. This will allow C++ extensions that pass 0 or NULL to macros using _Py_CAST() to continue to compile. Without this, you get an error like: invalid ‘static_cast’ from type ‘int’ to type ‘_object*’ The modern way to use a NULL value in C++ is to use nullptr. However, we want to not break extensions that do things the old way. Co-authored-by: serge-sans-paille
-rw-r--r--Include/pyport.h14
-rw-r--r--Lib/test/_testcppext.cpp4
-rw-r--r--Misc/NEWS.d/next/C API/2022-06-04-13-15-41.gh-issue-93442.4M4NDb.rst3
3 files changed, 21 insertions, 0 deletions
diff --git a/Include/pyport.h b/Include/pyport.h
index 6ea2bba..faaeb83 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -24,9 +24,23 @@
//
// The type argument must not be a constant type.
#ifdef __cplusplus
+#include <cstddef>
# define _Py_STATIC_CAST(type, expr) static_cast<type>(expr)
extern "C++" {
namespace {
+ template <typename type>
+ inline type _Py_CAST_impl(long int ptr) {
+ return reinterpret_cast<type>(ptr);
+ }
+ template <typename type>
+ inline type _Py_CAST_impl(int ptr) {
+ return reinterpret_cast<type>(ptr);
+ }
+ template <typename type>
+ inline type _Py_CAST_impl(std::nullptr_t) {
+ return static_cast<type>(nullptr);
+ }
+
template <typename type, typename expr_type>
inline type _Py_CAST_impl(expr_type *expr) {
return reinterpret_cast<type>(expr);
diff --git a/Lib/test/_testcppext.cpp b/Lib/test/_testcppext.cpp
index eade7cc..70f434e 100644
--- a/Lib/test/_testcppext.cpp
+++ b/Lib/test/_testcppext.cpp
@@ -74,6 +74,10 @@ test_api_casts(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
Py_INCREF(strong_ref);
Py_DECREF(strong_ref);
+ // gh-93442: Pass 0 as NULL for PyObject*
+ Py_XINCREF(0);
+ Py_XDECREF(0);
+
Py_DECREF(obj);
Py_RETURN_NONE;
}
diff --git a/Misc/NEWS.d/next/C API/2022-06-04-13-15-41.gh-issue-93442.4M4NDb.rst b/Misc/NEWS.d/next/C API/2022-06-04-13-15-41.gh-issue-93442.4M4NDb.rst
new file mode 100644
index 0000000..f48ed37
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2022-06-04-13-15-41.gh-issue-93442.4M4NDb.rst
@@ -0,0 +1,3 @@
+Add C++ overloads for _Py_CAST_impl() to handle 0/NULL. This will allow C++
+extensions that pass 0 or NULL to macros using _Py_CAST() to continue to
+compile.