]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-92898: Make _Py_Cast C++ version compatible with cast operator (gh-92951)
authorserge-sans-paille <serge.guelton@telecom-bretagne.eu>
Sat, 21 May 2022 13:16:37 +0000 (13:16 +0000)
committerGitHub <noreply@github.com>
Sat, 21 May 2022 13:16:37 +0000 (22:16 +0900)
Include/pyport.h
Lib/test/_testcppext.cpp

index 614a2789fb0781ec94b59e9c3e4589438823cdf8..086ed4204e4ff1f9583ab516e03d9c6de59d8aad 100644 (file)
 // _Py_CAST(const PyObject*, expr) fails with a compiler error.
 #ifdef __cplusplus
 #  define _Py_STATIC_CAST(type, expr) static_cast<type>(expr)
-#  define _Py_CAST(type, expr) \
-       const_cast<type>(reinterpret_cast<const type>(expr))
+
+extern "C++" {
+namespace {
+template <typename type, typename expr_type>
+inline type _Py_reinterpret_cast_impl(expr_type *expr) {
+  return reinterpret_cast<type>(expr);
+}
+
+template <typename type, typename expr_type>
+inline type _Py_reinterpret_cast_impl(expr_type const *expr) {
+  return reinterpret_cast<type>(const_cast<expr_type *>(expr));
+}
+
+template <typename type, typename expr_type>
+inline type _Py_reinterpret_cast_impl(expr_type &expr) {
+  return static_cast<type>(expr);
+}
+
+template <typename type, typename expr_type>
+inline type _Py_reinterpret_cast_impl(expr_type const &expr) {
+  return static_cast<type>(const_cast<expr_type &>(expr));
+}
+} // namespace
+}
+#  define _Py_CAST(type, expr) _Py_reinterpret_cast_impl<type>(expr)
+
 #else
 #  define _Py_STATIC_CAST(type, expr) ((type)(expr))
 #  define _Py_CAST(type, expr) ((type)(expr))
index f38b4870e0edbc10aa78190858aebf85452a62cc..f6049eedd0004807183b7b7f63699d9d87deaaab 100644 (file)
@@ -40,6 +40,15 @@ test_api_casts(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
     PyTypeObject *type = Py_TYPE(const_obj);
     assert(Py_REFCNT(const_obj) >= 1);
 
+    struct PyObjectProxy {
+      PyObject* obj;
+      operator PyObject *() { return obj; }
+    } proxy_obj = { obj };
+    Py_INCREF(proxy_obj);
+    Py_DECREF(proxy_obj);
+    assert(Py_REFCNT(proxy_obj) >= 1);
+
+
     assert(type == &PyTuple_Type);
     assert(PyTuple_GET_SIZE(const_obj) == 2);
     PyObject *one = PyTuple_GET_ITEM(const_obj, 0);