diff --git a/Makefile.pre.in b/Makefile.pre.in index 37ce0b55203cf7..0484605731cc4b 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -3313,7 +3313,7 @@ MODULE_CMATH_DEPS=$(srcdir)/Modules/_math.h MODULE_MATH_DEPS=$(srcdir)/Modules/_math.h MODULE_PYEXPAT_DEPS=@LIBEXPAT_INTERNAL@ MODULE_UNICODEDATA_DEPS=$(srcdir)/Modules/unicodedata_db.h $(srcdir)/Modules/unicodename_db.h -MODULE__CTYPES_DEPS=$(srcdir)/Modules/_ctypes/ctypes.h $(srcdir)/Modules/_complex.h +MODULE__CTYPES_DEPS=$(srcdir)/Modules/_ctypes/ctypes.h MODULE__CTYPES_TEST_DEPS=$(srcdir)/Modules/_ctypes/_ctypes_test_generated.c.h MODULE__CTYPES_MALLOC_CLOSURE=@MODULE__CTYPES_MALLOC_CLOSURE@ MODULE__DECIMAL_DEPS=$(srcdir)/Modules/_decimal/docstrings.h @LIBMPDEC_INTERNAL@ diff --git a/Modules/_complex.h b/Modules/_complex.h deleted file mode 100644 index 28d4a32794b97c..00000000000000 --- a/Modules/_complex.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Workarounds for buggy complex number arithmetic implementations. */ - -#ifndef Py_HAVE_C_COMPLEX -# error "this header file should only be included if Py_HAVE_C_COMPLEX is defined" -#endif - -#include - -/* Other compilers (than clang), that claims to - implement C11 *and* define __STDC_IEC_559_COMPLEX__ - don't have - issue with CMPLX(). This is specific to glibc & clang combination: - https://sourceware.org/bugzilla/show_bug.cgi?id=26287 - - Here we fallback to using __builtin_complex(), available in clang - v12+. Else CMPLX implemented following C11 6.2.5p13: "Each complex type - has the same representation and alignment requirements as an array - type containing exactly two elements of the corresponding real type; - the first element is equal to the real part, and the second element - to the imaginary part, of the complex number. - */ -#if !defined(CMPLX) -# if defined(__clang__) && __has_builtin(__builtin_complex) -# define CMPLX(x, y) __builtin_complex ((double) (x), (double) (y)) -# define CMPLXF(x, y) __builtin_complex ((float) (x), (float) (y)) -# define CMPLXL(x, y) __builtin_complex ((long double) (x), (long double) (y)) -# else -static inline double complex -CMPLX(double real, double imag) -{ - double complex z; - ((double *)(&z))[0] = real; - ((double *)(&z))[1] = imag; - return z; -} - -static inline float complex -CMPLXF(float real, float imag) -{ - float complex z; - ((float *)(&z))[0] = real; - ((float *)(&z))[1] = imag; - return z; -} - -static inline long double complex -CMPLXL(long double real, long double imag) -{ - long double complex z; - ((long double *)(&z))[0] = real; - ((long double *)(&z))[1] = imag; - return z; -} -# endif -#endif diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 2268072545f45d..557bfa85b1ea29 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -24,7 +24,7 @@ #endif #if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) -# include "../_complex.h" // csqrt() +# include // csqrt() # undef I // for _ctypes_test_generated.c.h #endif #include // printf() diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 83471aa3a42ad2..619e4ad08a65df 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -103,9 +103,6 @@ module _ctypes #include "pycore_global_objects.h"// _Py_ID() #include "pycore_traceback.h" // _PyTraceback_Add() -#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) -#include "../_complex.h" // complex -#endif #define clinic_state() (get_module_state(module)) #include "clinic/callproc.c.h" #undef clinic_state @@ -652,11 +649,9 @@ union result { double d; float f; void *p; -#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) - double complex D; - float complex F; - long double complex G; -#endif + double D[2]; + float F[2]; + long double G[2]; }; struct argument { diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 580ea18af2a43a..86bcc805360a3f 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -14,10 +14,6 @@ #include #include "ctypes.h" -#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) -# include "../_complex.h" // complex -#endif - #define CTYPES_CFIELD_CAPSULE_NAME_PYMEM "_ctypes/cfield.c pymem" /*[clinic input] @@ -763,18 +759,25 @@ d_get(void *ptr, Py_ssize_t size) return PyFloat_FromDouble(val); } -#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) +#if defined(Py_FFI_SUPPORT_C_COMPLEX) + +/* We don't use _Complex types here, using arrays instead, as the C11+ + standard says: "Each complex type has the same representation and alignment + requirements as an array type containing exactly two elements of the + corresponding real type; the first element is equal to the real part, and + the second element to the imaginary part, of the complex number." */ + /* D: double complex */ static PyObject * D_set(void *ptr, PyObject *value, Py_ssize_t size) { - assert(NUM_BITS(size) || (size == sizeof(double complex))); + assert(NUM_BITS(size) || (size == 2*sizeof(double))); Py_complex c = PyComplex_AsCComplex(value); if (c.real == -1 && PyErr_Occurred()) { return NULL; } - double complex x = CMPLX(c.real, c.imag); + double x[2] = {c.real, c.imag}; memcpy(ptr, &x, sizeof(x)); _RET(value); } @@ -782,24 +785,24 @@ D_set(void *ptr, PyObject *value, Py_ssize_t size) static PyObject * D_get(void *ptr, Py_ssize_t size) { - assert(NUM_BITS(size) || (size == sizeof(double complex))); - double complex x; + assert(NUM_BITS(size) || (size == 2*sizeof(double))); + double x[2]; memcpy(&x, ptr, sizeof(x)); - return PyComplex_FromDoubles(creal(x), cimag(x)); + return PyComplex_FromDoubles(x[0], x[1]); } /* F: float complex */ static PyObject * F_set(void *ptr, PyObject *value, Py_ssize_t size) { - assert(NUM_BITS(size) || (size == sizeof(float complex))); + assert(NUM_BITS(size) || (size == 2*sizeof(float))); Py_complex c = PyComplex_AsCComplex(value); if (c.real == -1 && PyErr_Occurred()) { return NULL; } - float complex x = CMPLXF((float)c.real, (float)c.imag); + float x[2] = {(float)c.real, (float)c.imag}; memcpy(ptr, &x, sizeof(x)); _RET(value); } @@ -807,24 +810,24 @@ F_set(void *ptr, PyObject *value, Py_ssize_t size) static PyObject * F_get(void *ptr, Py_ssize_t size) { - assert(NUM_BITS(size) || (size == sizeof(float complex))); - float complex x; + assert(NUM_BITS(size) || (size == 2*sizeof(float))); + float x[2]; memcpy(&x, ptr, sizeof(x)); - return PyComplex_FromDoubles(crealf(x), cimagf(x)); + return PyComplex_FromDoubles(x[0], x[1]); } /* G: long double complex */ static PyObject * G_set(void *ptr, PyObject *value, Py_ssize_t size) { - assert(NUM_BITS(size) || (size == sizeof(long double complex))); + assert(NUM_BITS(size) || (size == 2*sizeof(long double))); Py_complex c = PyComplex_AsCComplex(value); if (c.real == -1 && PyErr_Occurred()) { return NULL; } - long double complex x = CMPLXL(c.real, c.imag); + long double x[2] = {c.real, c.imag}; memcpy(ptr, &x, sizeof(x)); _RET(value); } @@ -832,11 +835,11 @@ G_set(void *ptr, PyObject *value, Py_ssize_t size) static PyObject * G_get(void *ptr, Py_ssize_t size) { - assert(NUM_BITS(size) || (size == sizeof(long double complex))); - long double complex x; + assert(NUM_BITS(size) || (size == 2*sizeof(long double))); + long double x[2]; memcpy(&x, ptr, sizeof(x)); - return PyComplex_FromDoubles((double)creall(x), (double)cimagl(x)); + return PyComplex_FromDoubles((double)x[0], (double)x[1]); } #endif @@ -1596,7 +1599,7 @@ for base_code, base_c_type in [ /////////////////////////////////////////////////////////////////////////// TABLE_ENTRY_SW(d, &ffi_type_double); -#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) +#if defined(Py_FFI_SUPPORT_C_COMPLEX) if (Py_FFI_COMPLEX_AVAILABLE) { TABLE_ENTRY(D, &ffi_type_complex_double); TABLE_ENTRY(F, &ffi_type_complex_float); diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 3b6d390728a07f..51ae71f7c6ef1e 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -11,8 +11,7 @@ // Do we support C99 complex types in ffi? // For Apple's libffi, this must be determined at runtime (see gh-128156). -#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) -# include "../_complex.h" // complex +#if defined(Py_FFI_SUPPORT_C_COMPLEX) # if USING_APPLE_OS_LIBFFI && defined(__has_builtin) # if __has_builtin(__builtin_available) # define Py_FFI_COMPLEX_AVAILABLE __builtin_available(macOS 10.15, *) @@ -493,11 +492,9 @@ struct tagPyCArgObject { double d; float f; void *p; -#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX) - double complex D; - float complex F; - long double complex G; -#endif + double D[2]; + float F[2]; + long double G[2]; } value; PyObject *obj; Py_ssize_t size; /* for the 'V' tag */ diff --git a/Modules/_struct.c b/Modules/_struct.c index e400f607b558dc..c36079f1eb8886 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -853,8 +853,8 @@ static const formatdef native_table[] = { {'e', sizeof(short), _Alignof(short), nu_halffloat, np_halffloat}, {'f', sizeof(float), _Alignof(float), nu_float, np_float}, {'d', sizeof(double), _Alignof(double), nu_double, np_double}, - {'F', 2*sizeof(float), _Alignof(float[2]), nu_float_complex, np_float_complex}, - {'D', 2*sizeof(double), _Alignof(double[2]), nu_double_complex, np_double_complex}, + {'F', 2*sizeof(float), _Alignof(float), nu_float_complex, np_float_complex}, + {'D', 2*sizeof(double), _Alignof(double), nu_double_complex, np_double_complex}, {'P', sizeof(void *), _Alignof(void *), nu_void_p, np_void_p}, {0} };