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@
+++ /dev/null
-/* 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 <complex.h>
-
-/* 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
#endif
#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
-# include "../_complex.h" // csqrt()
+# include <complex.h> // csqrt()
# undef I // for _ctypes_test_generated.c.h
#endif
#include <stdio.h> // printf()
#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
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 {
#include <ffi.h>
#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]
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);
}
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);
}
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);
}
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
///////////////////////////////////////////////////////////////////////////
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);
// 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, *)
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 */
{'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}
};