]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-91320: Fix more old-style cast warnings in C++ (#92247)
authorVictor Stinner <vstinner@python.org>
Tue, 3 May 2022 18:47:29 +0000 (20:47 +0200)
committerGitHub <noreply@github.com>
Tue, 3 May 2022 18:47:29 +0000 (20:47 +0200)
Use _Py_CAST(), _Py_STATIC_CAST() and _PyASCIIObject_CAST() in
static inline functions to fix C++ compiler warnings:
"use of old-style cast" (clang -Wold-style-cast).

test_cppext now builds the C++ test extension with -Wold-style-cast.

Include/cpython/unicodeobject.h
Include/cpython/weakrefobject.h
Lib/test/test_cppext.py

index 47194ac7829fd70dd00fe90f93b4e42de9b7eab7..96bfaaf4d2badde291c0eed46cbb97cf0497faf0 100644 (file)
@@ -314,16 +314,15 @@ enum PyUnicode_Kind {
 
 /* Return one of the PyUnicode_*_KIND values defined above. */
 #define PyUnicode_KIND(op) \
-    (assert(PyUnicode_Check(op)), \
-     assert(PyUnicode_IS_READY(op)), \
-     ((PyASCIIObject *)(op))->state.kind)
+    (assert(PyUnicode_IS_READY(op)), \
+     _PyASCIIObject_CAST(op)->state.kind)
 
 /* Return a void pointer to the raw unicode buffer. */
 static inline void* _PyUnicode_COMPACT_DATA(PyObject *op) {
     if (PyUnicode_IS_ASCII(op)) {
-        return (void*)(_PyASCIIObject_CAST(op) + 1);
+        return _Py_STATIC_CAST(void*, (_PyASCIIObject_CAST(op) + 1));
     }
-    return (void*)(_PyCompactUnicodeObject_CAST(op) + 1);
+    return _Py_STATIC_CAST(void*, (_PyCompactUnicodeObject_CAST(op) + 1));
 }
 
 static inline void* _PyUnicode_NONCOMPACT_DATA(PyObject *op) {
@@ -348,9 +347,9 @@ static inline void* PyUnicode_DATA(PyObject *op) {
    No checks are performed, use PyUnicode_KIND() before to ensure
    these will work correctly. */
 
-#define PyUnicode_1BYTE_DATA(op) ((Py_UCS1*)PyUnicode_DATA(op))
-#define PyUnicode_2BYTE_DATA(op) ((Py_UCS2*)PyUnicode_DATA(op))
-#define PyUnicode_4BYTE_DATA(op) ((Py_UCS4*)PyUnicode_DATA(op))
+#define PyUnicode_1BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS1*, PyUnicode_DATA(op))
+#define PyUnicode_2BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS2*, PyUnicode_DATA(op))
+#define PyUnicode_4BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS4*, PyUnicode_DATA(op))
 
 /* Returns the length of the unicode string. The caller has to make sure that
    the string has it's canonical representation set before calling
@@ -373,16 +372,16 @@ static inline void PyUnicode_WRITE(unsigned int kind, void *data,
 {
     if (kind == PyUnicode_1BYTE_KIND) {
         assert(value <= 0xffU);
-        ((Py_UCS1 *)data)[index] = (Py_UCS1)value;
+        _Py_STATIC_CAST(Py_UCS1*, data)[index] = _Py_STATIC_CAST(Py_UCS1, value);
     }
     else if (kind == PyUnicode_2BYTE_KIND) {
         assert(value <= 0xffffU);
-        ((Py_UCS2 *)data)[index] = (Py_UCS2)value;
+        _Py_STATIC_CAST(Py_UCS2*, data)[index] = _Py_STATIC_CAST(Py_UCS2, value);
     }
     else {
         assert(kind == PyUnicode_4BYTE_KIND);
         assert(value <= 0x10ffffU);
-        ((Py_UCS4 *)data)[index] = value;
+        _Py_STATIC_CAST(Py_UCS4*, data)[index] = value;
     }
 }
 #define PyUnicode_WRITE(kind, data, index, value) \
@@ -394,13 +393,13 @@ static inline Py_UCS4 PyUnicode_READ(unsigned int kind,
                                      const void *data, Py_ssize_t index)
 {
     if (kind == PyUnicode_1BYTE_KIND) {
-        return ((const Py_UCS1 *)data)[index];
+        return _Py_STATIC_CAST(const Py_UCS1*, data)[index];
     }
     if (kind == PyUnicode_2BYTE_KIND) {
-        return ((const Py_UCS2 *)data)[index];
+        return _Py_STATIC_CAST(const Py_UCS2*, data)[index];
     }
     assert(kind == PyUnicode_4BYTE_KIND);
-    return ((const Py_UCS4 *)data)[index];
+    return _Py_STATIC_CAST(const Py_UCS4*, data)[index];
 }
 #define PyUnicode_READ(kind, data, index) \
     PyUnicode_READ((unsigned int)(kind), (const void*)(data), (index))
@@ -693,7 +692,9 @@ static inline const char* PyUnicode_AS_DATA(PyObject *op)
 {
     _Py_COMP_DIAG_PUSH
     _Py_COMP_DIAG_IGNORE_DEPR_DECLS
-    return (const char *)PyUnicode_AS_UNICODE(op);
+    Py_UNICODE *data = PyUnicode_AS_UNICODE(op);
+    // In C++, casting directly PyUnicode* to const char* is not valid
+    return _Py_STATIC_CAST(const char*, _Py_STATIC_CAST(const void*, data));
     _Py_COMP_DIAG_POP
 }
 #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
index 1078fffc2e0a5fd33cfbba4a23ddfa1fea646a75..bec69ba90d6b986cf32262d05d8d19def7eb4321 100644 (file)
@@ -38,7 +38,7 @@ PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);
 
 static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj) {
     assert(PyWeakref_Check(ref_obj));
-    PyWeakReference *ref = (PyWeakReference *)ref_obj;
+    PyWeakReference *ref = _Py_CAST(PyWeakReference*, ref_obj);
     PyObject *obj = ref->wr_object;
     // Explanation for the Py_REFCNT() check: when a weakref's target is part
     // of a long chain of deallocations which triggers the trashcan mechanism,
index 99f6062d79d478f89dbaad22c9ee71fa66854a14..fbb79bb8ac3ed1babc3656da0cb9f51dd5232200 100644 (file)
@@ -27,6 +27,8 @@ if not MS_WINDOWS:
         # a C++ extension using the Python C API does not emit C++ compiler
         # warnings
         '-Werror',
+        # Warn on old-style cast (C cast) like: (PyObject*)op
+        '-Wold-style-cast',
     ]
 else:
     # Don't pass any compiler flag to MSVC