summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2014-01-20 15:18:55 +0100
committerArmin Rigo <arigo@tunes.org>2014-01-20 15:18:55 +0100
commitffe751a21307d6be3eaba9ed7eb2370d7a77c32c (patch)
treead06ea3351637dec484bbf37f272cc58e50a2f02
parent142f525c0112cc6494a4d678466436c0952e6303 (diff)
downloadcffi-ffe751a21307d6be3eaba9ed7eb2370d7a77c32c.tar.gz
Raise a NotImplementedError in one messy corner case
-rw-r--r--c/_cffi_backend.c8
-rw-r--r--c/test_c.py10
2 files changed, 18 insertions, 0 deletions
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
index 7aefbd3..a1292c0 100644
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -3817,6 +3817,14 @@ static PyObject *b_complete_struct_or_union(PyObject *self, PyObject *args)
if (bits_already_occupied + fbitsize > 8 * ftype->ct_size) {
/* it would not fit, we need to start at the next
allowed position */
+ if ((sflags & SF_PACKED) &&
+ (bits_already_occupied & 7)) {
+ PyErr_Format(PyExc_NotImplementedError,
+ "with 'packed', gcc would compile field "
+ "'%s.%s' to reuse some bits in the previous "
+ "field", ct->ct_name, PyText_AS_UTF8(fname));
+ goto error;
+ }
field_offset_bytes += falign;
assert(boffset < field_offset_bytes * 8);
boffset = field_offset_bytes * 8;
diff --git a/c/test_c.py b/c/test_c.py
index 005a089..09d0a13 100644
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -3177,6 +3177,16 @@ def test_packed():
assert sizeof(BStruct) == sizeof(BLong) + sizeof(BChar) + sizeof(BShort)
assert alignof(BStruct) == 1
+def test_packed_with_bitfields():
+ BLong = new_primitive_type("long")
+ BChar = new_primitive_type("char")
+ BStruct = new_struct_type("struct foo")
+ py.test.raises(NotImplementedError,
+ complete_struct_or_union,
+ BStruct, [('a1', BLong, 30),
+ ('a2', BChar, 5)],
+ None, -1, -1, 8) # SF_PACKED==8
+
def test_version():
# this test is here mostly for PyPy
assert __version__ == "0.8"