cpython: 3fbfa61634de (original) (raw)

--- a/Lib/ctypes/test/test_bitfields.py +++ b/Lib/ctypes/test/test_bitfields.py @@ -240,5 +240,25 @@ class BitFieldTest(unittest.TestCase): anonymous = [""] fields = [("", X)]

+

+ if name == "main": unittest.main()

--- a/Misc/NEWS +++ b/Misc/NEWS @@ -138,6 +138,9 @@ C API Extension Modules ----------------- +- Issue #6493: An issue in ctypes on Windows that caused structure bitfields

--- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -427,12 +427,8 @@ get_ulonglong(PyObject v, unsigned PY_L #define LOW_BIT(x) ((x) & 0xFFFF) #define NUM_BITS(x) ((x) >> 16) -/ This seems nore a compiler issue than a Windows/non-Windows one / -#ifdef MS_WIN32 -# define BIT_MASK(size) ((1 << NUM_BITS(size))-1) -#else -# define BIT_MASK(size) ((1LL << NUM_BITS(size))-1) -#endif +/ Doesn't work if NUM_BITS(size) == 0, but it never happens in SET() call. / +#define BIT_MASK(type, size) (((((type)1 << (NUM_BITS(size) - 1)) - 1) << 1) + 1) / This macro CHANGES the first parameter IN PLACE. For proper sign handling, we must first shift left, then right. @@ -444,10 +440,10 @@ get_ulonglong(PyObject v, unsigned PY_L } / This macro RETURNS the first parameter with the bit field CHANGED. */ -#define SET(x, v, size) [](#l3.22) +#define SET(type, x, v, size) [](#l3.23) (NUM_BITS(size) ? [](#l3.24)

/* byte swapping macros */ #define SWAP_2(v) [](#l3.31) @@ -519,7 +515,7 @@ b_set(void *ptr, PyObject *value, Py_ssi long val; if (get_long(value, &val) < 0) return NULL;

@@ -538,8 +534,7 @@ B_set(void *ptr, PyObject *value, Py_ssi unsigned long val; if (get_ulong(value, &val) < 0) return NULL;

@@ -560,7 +555,7 @@ h_set(void *ptr, PyObject *value, Py_ssi if (get_long(value, &val) < 0) return NULL; memcpy(&x, ptr, sizeof(x));

@@ -575,7 +570,7 @@ h_set_sw(void *ptr, PyObject *value, Py_ return NULL; memcpy(&field, ptr, sizeof(field)); field = SWAP_2(field);

@@ -622,7 +617,7 @@ H_set_sw(void *ptr, PyObject *value, Py_ return NULL; memcpy(&field, ptr, sizeof(field)); field = SWAP_2(field);

@@ -670,7 +665,7 @@ i_set_sw(void *ptr, PyObject *value, Py_ return NULL; memcpy(&field, ptr, sizeof(field)); field = SWAP_INT(field);

@@ -770,7 +765,7 @@ I_set_sw(void *ptr, PyObject *value, Py_ if (get_ulong(value, &val) < 0) return NULL; memcpy(&field, ptr, sizeof(field));

@@ -818,7 +813,7 @@ l_set_sw(void *ptr, PyObject *value, Py_ return NULL; memcpy(&field, ptr, sizeof(field)); field = SWAP_LONG(field);

@@ -866,7 +861,7 @@ L_set_sw(void *ptr, PyObject *value, Py_ return NULL; memcpy(&field, ptr, sizeof(field)); field = SWAP_LONG(field);

@@ -915,7 +910,7 @@ q_set_sw(void *ptr, PyObject *value, Py_ return NULL; memcpy(&field, ptr, sizeof(field)); field = SWAP_8(field);

@@ -962,7 +957,7 @@ Q_set_sw(void *ptr, PyObject *value, Py_ return NULL; memcpy(&field, ptr, sizeof(field)); field = SWAP_8(field);