Skip to content

Commit efbe0bb

Browse files
committed
gh-61103: don't use native complex types to implement F/D/G in ctypes
* drop _complex.h header * use appropriate real arrays to replace complex types
1 parent 66d7e54 commit efbe0bb

File tree

5 files changed

+32
-91
lines changed

5 files changed

+32
-91
lines changed

Makefile.pre.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -3313,7 +3313,7 @@ MODULE_CMATH_DEPS=$(srcdir)/Modules/_math.h
33133313
MODULE_MATH_DEPS=$(srcdir)/Modules/_math.h
33143314
MODULE_PYEXPAT_DEPS=@LIBEXPAT_INTERNAL@
33153315
MODULE_UNICODEDATA_DEPS=$(srcdir)/Modules/unicodedata_db.h $(srcdir)/Modules/unicodename_db.h
3316-
MODULE__CTYPES_DEPS=$(srcdir)/Modules/_ctypes/ctypes.h $(srcdir)/Modules/_complex.h
3316+
MODULE__CTYPES_DEPS=$(srcdir)/Modules/_ctypes/ctypes.h
33173317
MODULE__CTYPES_TEST_DEPS=$(srcdir)/Modules/_ctypes/_ctypes_test_generated.c.h
33183318
MODULE__CTYPES_MALLOC_CLOSURE=@MODULE__CTYPES_MALLOC_CLOSURE@
33193319
MODULE__DECIMAL_DEPS=$(srcdir)/Modules/_decimal/docstrings.h @LIBMPDEC_INTERNAL@

Modules/_complex.h

-54
This file was deleted.

Modules/_ctypes/callproc.c

+3-8
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,6 @@ module _ctypes
103103
#include "pycore_global_objects.h"// _Py_ID()
104104
#include "pycore_traceback.h" // _PyTraceback_Add()
105105

106-
#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
107-
#include "../_complex.h" // complex
108-
#endif
109106
#define clinic_state() (get_module_state(module))
110107
#include "clinic/callproc.c.h"
111108
#undef clinic_state
@@ -652,11 +649,9 @@ union result {
652649
double d;
653650
float f;
654651
void *p;
655-
#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
656-
double complex D;
657-
float complex F;
658-
long double complex G;
659-
#endif
652+
double D[2];
653+
float F[2];
654+
long double G[2];
660655
};
661656

662657
struct argument {

Modules/_ctypes/cfield.c

+24-21
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@
1414
#include <ffi.h>
1515
#include "ctypes.h"
1616

17-
#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
18-
# include "../_complex.h" // complex
19-
#endif
20-
2117
#define CTYPES_CFIELD_CAPSULE_NAME_PYMEM "_ctypes/cfield.c pymem"
2218

2319
/*[clinic input]
@@ -763,80 +759,87 @@ d_get(void *ptr, Py_ssize_t size)
763759
return PyFloat_FromDouble(val);
764760
}
765761

766-
#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
762+
#if defined(Py_FFI_SUPPORT_C_COMPLEX)
763+
764+
/* We don't use Annex G complex types here, using arrays instead, as the C17+
765+
standard says: "Each complex type has the same representation and alignment
766+
requirements as an array type containing exactly two elements of the
767+
corresponding real type; the first element is equal to the real part, and
768+
the second element to the imaginary part, of the complex number." */
769+
767770
/* D: double complex */
768771
static PyObject *
769772
D_set(void *ptr, PyObject *value, Py_ssize_t size)
770773
{
771-
assert(NUM_BITS(size) || (size == sizeof(double complex)));
774+
assert(NUM_BITS(size) || (size == 2*sizeof(double)));
772775
Py_complex c = PyComplex_AsCComplex(value);
773776

774777
if (c.real == -1 && PyErr_Occurred()) {
775778
return NULL;
776779
}
777-
double complex x = CMPLX(c.real, c.imag);
780+
double x[2] = {c.real, c.imag};
778781
memcpy(ptr, &x, sizeof(x));
779782
_RET(value);
780783
}
781784

782785
static PyObject *
783786
D_get(void *ptr, Py_ssize_t size)
784787
{
785-
assert(NUM_BITS(size) || (size == sizeof(double complex)));
786-
double complex x;
788+
assert(NUM_BITS(size) || (size == 2*sizeof(double)));
789+
double x[2];
787790

788791
memcpy(&x, ptr, sizeof(x));
789-
return PyComplex_FromDoubles(creal(x), cimag(x));
792+
return PyComplex_FromDoubles(x[0], x[1]);
790793
}
791794

792795
/* F: float complex */
793796
static PyObject *
794797
F_set(void *ptr, PyObject *value, Py_ssize_t size)
795798
{
796-
assert(NUM_BITS(size) || (size == sizeof(float complex)));
799+
assert(NUM_BITS(size) || (size == 2*sizeof(float)));
797800
Py_complex c = PyComplex_AsCComplex(value);
798801

799802
if (c.real == -1 && PyErr_Occurred()) {
800803
return NULL;
801804
}
802-
float complex x = CMPLXF((float)c.real, (float)c.imag);
805+
float x[2] = {(float)c.real, (float)c.imag};
803806
memcpy(ptr, &x, sizeof(x));
804807
_RET(value);
805808
}
806809

807810
static PyObject *
808811
F_get(void *ptr, Py_ssize_t size)
809812
{
810-
assert(NUM_BITS(size) || (size == sizeof(float complex)));
811-
float complex x;
813+
assert(NUM_BITS(size) || (size == 2*sizeof(float)));
814+
float x[2];
812815

813816
memcpy(&x, ptr, sizeof(x));
814-
return PyComplex_FromDoubles(crealf(x), cimagf(x));
817+
return PyComplex_FromDoubles(x[0], x[1]);
815818
}
816819

817820
/* G: long double complex */
818821
static PyObject *
819822
G_set(void *ptr, PyObject *value, Py_ssize_t size)
820823
{
821-
assert(NUM_BITS(size) || (size == sizeof(long double complex)));
824+
assert(NUM_BITS(size) || (size == 2*sizeof(long double)));
822825
Py_complex c = PyComplex_AsCComplex(value);
823826

824827
if (c.real == -1 && PyErr_Occurred()) {
825828
return NULL;
826829
}
827-
long double complex x = CMPLXL(c.real, c.imag);
830+
long double x[2] = {c.real, c.imag};
828831
memcpy(ptr, &x, sizeof(x));
829832
_RET(value);
830833
}
831834

832835
static PyObject *
833836
G_get(void *ptr, Py_ssize_t size)
834837
{
835-
assert(NUM_BITS(size) || (size == sizeof(long double complex)));
836-
long double complex x;
838+
assert(NUM_BITS(size) || (size == 2*sizeof(long double)));
839+
long double x[2];
837840

838841
memcpy(&x, ptr, sizeof(x));
839-
return PyComplex_FromDoubles((double)creall(x), (double)cimagl(x));
842+
return PyComplex_FromDoubles((double)x[0], (double)x[1]);
840843
}
841844
#endif
842845

@@ -1596,7 +1599,7 @@ for base_code, base_c_type in [
15961599
///////////////////////////////////////////////////////////////////////////
15971600

15981601
TABLE_ENTRY_SW(d, &ffi_type_double);
1599-
#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
1602+
#if defined(Py_FFI_SUPPORT_C_COMPLEX)
16001603
if (Py_FFI_COMPLEX_AVAILABLE) {
16011604
TABLE_ENTRY(D, &ffi_type_complex_double);
16021605
TABLE_ENTRY(F, &ffi_type_complex_float);

Modules/_ctypes/ctypes.h

+4-7
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111

1212
// Do we support C99 complex types in ffi?
1313
// For Apple's libffi, this must be determined at runtime (see gh-128156).
14-
#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
15-
# include "../_complex.h" // complex
14+
#if defined(Py_FFI_SUPPORT_C_COMPLEX)
1615
# if USING_APPLE_OS_LIBFFI && defined(__has_builtin)
1716
# if __has_builtin(__builtin_available)
1817
# define Py_FFI_COMPLEX_AVAILABLE __builtin_available(macOS 10.15, *)
@@ -493,11 +492,9 @@ struct tagPyCArgObject {
493492
double d;
494493
float f;
495494
void *p;
496-
#if defined(Py_HAVE_C_COMPLEX) && defined(Py_FFI_SUPPORT_C_COMPLEX)
497-
double complex D;
498-
float complex F;
499-
long double complex G;
500-
#endif
495+
double D[2];
496+
float F[2];
497+
long double G[2];
501498
} value;
502499
PyObject *obj;
503500
Py_ssize_t size; /* for the 'V' tag */

0 commit comments

Comments
 (0)