Author: Armin Rigo <[email protected]>
Branch:
Changeset: r1266:263caa88878e
Date: 2013-06-01 13:34 +0200
http://bitbucket.org/cffi/cffi/changeset/263caa88878e/
Log: Fix MSVC bitfields in all tested cases.
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -3477,7 +3477,7 @@
for (i=0; i<nb_fields; i++) {
PyObject *fname;
CTypeDescrObject *ftype;
- int fbitsize = -1, falign, foffset = -1;
+ int fbitsize = -1, falign, do_align, foffset = -1;
if (!PyArg_ParseTuple(PyList_GET_ITEM(fields, i), "O!O!|ii:list item",
&PyText_Type, &fname,
@@ -3501,7 +3501,19 @@
falign = get_alignment(ftype);
if (falign < 0)
goto error;
- if (alignment < falign && (fbitsize < 0 || PyText_GetSize(fname) > 0))
+
+ do_align = 1;
+ if (fbitsize >= 0) {
+ if (!(sflags & SF_MSVC_BITFIELDS)) {
+ /* GCC: anonymous bitfields (of any size) don't cause
alignment */
+ do_align = PyText_GetSize(fname) > 0;
+ }
+ else {
+ /* MSVC: zero-sized bitfields don't cause alignment */
+ do_align = fbitsize > 0;
+ }
+ }
+ if (alignment < falign && do_align)
alignment = falign;
if (fbitsize < 0) {
@@ -3598,11 +3610,23 @@
"field '%s.%s' is declared with :0",
ct->ct_name, PyText_AS_UTF8(fname));
}
- if (boffset > field_offset_bytes * 8) {
- field_offset_bytes += falign;
- assert(boffset < field_offset_bytes * 8);
+ if (!(sflags & SF_MSVC_BITFIELDS)) {
+ /* GCC's notion of "ftype :0;" */
+
+ /* pad boffset to a value aligned for "ftype" */
+ if (boffset > field_offset_bytes * 8) {
+ field_offset_bytes += falign;
+ assert(boffset < field_offset_bytes * 8);
+ }
+ boffset = field_offset_bytes * 8;
}
- boffset = field_offset_bytes * 8; /* the only effect */
+ else {
+ /* MSVC's notion of "ftype :0;" */
+
+ /* Mostly ignored. It seems they only serve as
+ separator between other bitfields, to force them
+ into separate words. */
+ }
prev_bitfield_size = 0;
}
else {
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -2791,16 +2791,24 @@
('', BShort, 9),
('c', BChar, -1)], -1, -1, -1, flag)
assert typeoffsetof(BStruct, 'c') == (BChar, 4)
- assert sizeof(BStruct) == 5
- assert alignof(BStruct) == 1
+ if flag == 0: # gcc
+ assert sizeof(BStruct) == 5
+ assert alignof(BStruct) == 1
+ else: # msvc
+ assert sizeof(BStruct) == 6
+ assert alignof(BStruct) == 2
#
BStruct = new_struct_type("foo2")
complete_struct_or_union(BStruct, [('a', BChar, -1),
('', BInt, 0),
('', BInt, 0),
('c', BChar, -1)], -1, -1, -1, flag)
- assert typeoffsetof(BStruct, 'c') == (BChar, 4)
- assert sizeof(BStruct) == 5
+ if flag == 0: # gcc
+ assert typeoffsetof(BStruct, 'c') == (BChar, 4)
+ assert sizeof(BStruct) == 5
+ else: # msvc
+ assert typeoffsetof(BStruct, 'c') == (BChar, 1)
+ assert sizeof(BStruct) == 2
assert alignof(BStruct) == 1
diff --git a/testing/test_ffi_backend.py b/testing/test_ffi_backend.py
--- a/testing/test_ffi_backend.py
+++ b/testing/test_ffi_backend.py
@@ -137,6 +137,7 @@
L = FFI().alignof("long long")
self.check("char y; int :0;", 0, 1, 4)
self.check("char x; int :0; char y;", 4, 1, 5)
+ self.check("char x; int :0; int :0; char y;", 4, 1, 5)
self.check("char x; long long :0; char y;", L, 1, L + 1)
self.check("short x, y; int :0; int :0;", 2, 2, 4)
self.check("char x; int :0; short b:1; char y;", 5, 2, 6)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit