[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