gh-91320: Fix more old-style cast warnings in C++ (#92247)

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.
This commit is contained in:
Victor Stinner 2022-05-03 20:47:29 +02:00 committed by GitHub
parent b270b82f11
commit ff3e9cdf33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 16 deletions

View file

@ -314,16 +314,15 @@ enum PyUnicode_Kind {
/* Return one of the PyUnicode_*_KIND values defined above. */ /* Return one of the PyUnicode_*_KIND values defined above. */
#define PyUnicode_KIND(op) \ #define PyUnicode_KIND(op) \
(assert(PyUnicode_Check(op)), \ (assert(PyUnicode_IS_READY(op)), \
assert(PyUnicode_IS_READY(op)), \ _PyASCIIObject_CAST(op)->state.kind)
((PyASCIIObject *)(op))->state.kind)
/* Return a void pointer to the raw unicode buffer. */ /* Return a void pointer to the raw unicode buffer. */
static inline void* _PyUnicode_COMPACT_DATA(PyObject *op) { static inline void* _PyUnicode_COMPACT_DATA(PyObject *op) {
if (PyUnicode_IS_ASCII(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) { 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 No checks are performed, use PyUnicode_KIND() before to ensure
these will work correctly. */ these will work correctly. */
#define PyUnicode_1BYTE_DATA(op) ((Py_UCS1*)PyUnicode_DATA(op)) #define PyUnicode_1BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS1*, PyUnicode_DATA(op))
#define PyUnicode_2BYTE_DATA(op) ((Py_UCS2*)PyUnicode_DATA(op)) #define PyUnicode_2BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS2*, PyUnicode_DATA(op))
#define PyUnicode_4BYTE_DATA(op) ((Py_UCS4*)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 /* Returns the length of the unicode string. The caller has to make sure that
the string has it's canonical representation set before calling 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) { if (kind == PyUnicode_1BYTE_KIND) {
assert(value <= 0xffU); 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) { else if (kind == PyUnicode_2BYTE_KIND) {
assert(value <= 0xffffU); assert(value <= 0xffffU);
((Py_UCS2 *)data)[index] = (Py_UCS2)value; _Py_STATIC_CAST(Py_UCS2*, data)[index] = _Py_STATIC_CAST(Py_UCS2, value);
} }
else { else {
assert(kind == PyUnicode_4BYTE_KIND); assert(kind == PyUnicode_4BYTE_KIND);
assert(value <= 0x10ffffU); assert(value <= 0x10ffffU);
((Py_UCS4 *)data)[index] = value; _Py_STATIC_CAST(Py_UCS4*, data)[index] = value;
} }
} }
#define PyUnicode_WRITE(kind, 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) const void *data, Py_ssize_t index)
{ {
if (kind == PyUnicode_1BYTE_KIND) { 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) { 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); 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) \ #define PyUnicode_READ(kind, data, index) \
PyUnicode_READ((unsigned int)(kind), (const void*)(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_PUSH
_Py_COMP_DIAG_IGNORE_DEPR_DECLS _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 _Py_COMP_DIAG_POP
} }
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000

View file

@ -38,7 +38,7 @@ PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self);
static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj) { static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj) {
assert(PyWeakref_Check(ref_obj)); assert(PyWeakref_Check(ref_obj));
PyWeakReference *ref = (PyWeakReference *)ref_obj; PyWeakReference *ref = _Py_CAST(PyWeakReference*, ref_obj);
PyObject *obj = ref->wr_object; PyObject *obj = ref->wr_object;
// Explanation for the Py_REFCNT() check: when a weakref's target is part // Explanation for the Py_REFCNT() check: when a weakref's target is part
// of a long chain of deallocations which triggers the trashcan mechanism, // of a long chain of deallocations which triggers the trashcan mechanism,

View file

@ -27,6 +27,8 @@ if not MS_WINDOWS:
# a C++ extension using the Python C API does not emit C++ compiler # a C++ extension using the Python C API does not emit C++ compiler
# warnings # warnings
'-Werror', '-Werror',
# Warn on old-style cast (C cast) like: (PyObject*)op
'-Wold-style-cast',
] ]
else: else:
# Don't pass any compiler flag to MSVC # Don't pass any compiler flag to MSVC