[pypy-commit] cffi default: Issue #412
arigo
pypy.commits at gmail.com
Wed Jun 12 11:58:35 EDT 2019
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r3279:e00484ba0031
Date: 2019-06-12 17:58 +0200
http://bitbucket.org/cffi/cffi/changeset/e00484ba0031/
Log: Issue #412
Test and fix for unnamed bitfields which are not ":0" bitfields.
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -5275,16 +5275,18 @@
prev_bitfield_free -= fbitsize;
field_offset_bytes = boffset / 8 - ftype->ct_size;
}
-
if (sflags & SF_GCC_BIG_ENDIAN)
bitshift = 8 * ftype->ct_size - fbitsize - bitshift;
- *previous = _add_field(interned_fields, fname, ftype,
+ if (PyText_GetSize(fname) > 0) {
+
+ *previous = _add_field(interned_fields, fname, ftype,
field_offset_bytes, bitshift, fbitsize,
fflags);
- if (*previous == NULL)
- goto error;
- previous = &(*previous)->cf_next;
+ if (*previous == NULL)
+ goto error;
+ previous = &(*previous)->cf_next;
+ }
}
}
diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -855,8 +855,9 @@
try:
if ftype.is_integer_type() or fbitsize >= 0:
# accept all integers, but complain on float or double
- prnt(" (void)((p->%s) | 0); /* check that '%s.%s' is "
- "an integer */" % (fname, cname, fname))
+ if fname != '':
+ prnt(" (void)((p->%s) | 0); /* check that '%s.%s' is "
+ "an integer */" % (fname, cname, fname))
continue
# only accept exactly the type declared, except that '[]'
# is interpreted as a '*' and so will match any array length.
diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -2359,3 +2359,56 @@
assert q[0].a == p.a
assert q[0].b == p.b
assert q == p
+
+def test_unnamed_bitfield_1():
+ ffi = FFI()
+ ffi.cdef("""struct A { char : 1; };""")
+ lib = verify(ffi, "test_unnamed_bitfield_1", """
+ struct A { char : 1; };
+ """)
+ p = ffi.new("struct A *")
+ assert ffi.sizeof(p[0]) == 1
+ # Note: on gcc, the type name is ignored for anonymous bitfields
+ # and that's why the result is 1. On MSVC, the result is
+ # sizeof("char") which is also 1.
+
+def test_unnamed_bitfield_2():
+ ffi = FFI()
+ ffi.cdef("""struct A {
+ short c : 1; short : 1; short d : 1; short : 1; };""")
+ lib = verify(ffi, "test_unnamed_bitfield_2", """
+ struct A {
+ short c : 1; short : 1; short d : 1; short : 1;
+ };
+ """)
+ p = ffi.new("struct A *")
+ assert ffi.sizeof(p[0]) == ffi.sizeof("short")
+
+def test_unnamed_bitfield_3():
+ ffi = FFI()
+ ffi.cdef("""struct A { struct { char : 1; char : 1; } b; };""")
+ lib = verify(ffi, "test_unnamed_bitfield_3", """
+ struct A { struct { char : 1; char : 1; } b; };
+ """)
+ p = ffi.new("struct A *")
+ assert ffi.sizeof(p[0]) == 1
+ # Note: on gcc, the type name is ignored for anonymous bitfields
+ # and that's why the result is 1. On MSVC, the result is
+ # sizeof("char") which is also 1.
+
+def test_unnamed_bitfield_4():
+ ffi = FFI()
+ ffi.cdef("""struct A { struct {
+ unsigned c : 1; unsigned : 1; unsigned d : 1; unsigned : 1; } a;
+ };
+ struct B { struct A a; };""")
+ lib = verify(ffi, "test_unnamed_bitfield_4", """
+ struct A { struct {
+ unsigned c : 1; unsigned : 1; unsigned d : 1; unsigned : 1; } a;
+ };
+ struct B { struct A a; };
+ """)
+ b = ffi.new("struct B *")
+ a = ffi.new("struct A *")
+ assert ffi.sizeof(a[0]) == ffi.sizeof("unsigned")
+ assert ffi.sizeof(b[0]) == ffi.sizeof(a[0])
More information about the pypy-commit
mailing list