summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-06-13 19:08:22 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-06-13 19:08:22 -0700
commited73979d131383a082efa7d6e588ffe47464bb89 (patch)
treedb1c37636d8341d68c455f73e5a64b5edf58a98b
parentb24c90c1f41eaf04b8989a419d04894c70da42f8 (diff)
downloadtxr-ed73979d131383a082efa7d6e588ffe47464bb89.tar.gz
txr-ed73979d131383a082efa7d6e588ffe47464bb89.tar.bz2
txr-ed73979d131383a082efa7d6e588ffe47464bb89.zip
ffi: fix buggy bitfield allocation.
* ffi.c (make_ffi_type_struct): When there is no room in the current bitfield, two mistakes are made. When bit_offs is reset to zero in this case, the dependent variable bits_alloc that was calculated from it (bits allocated to current unit) must also be reset. The subsequent shift depends on it. Secondly, when we establish the memb[i].offs field, that must come from offs, not from unit_offs, because unit_offs is always the base offset of the existing cell (which doesn't have room for the new bitfield in this case); the main offset variable offs is what gets gets adjusted to the cell which has room for the new bitfield.
-rw-r--r--ffi.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/ffi.c b/ffi.c
index beef8d1e..8776aad4 100644
--- a/ffi.c
+++ b/ffi.c
@@ -2796,7 +2796,7 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
if (bits > room) {
offs = unit_offs + size;
- bit_offs = 0;
+ bit_offs = bits_alloc = 0;
}
if (bits_alloc == 0) {
@@ -2804,7 +2804,7 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
most_align = mtft->align;
}
- memb[i].offs = unit_offs;
+ memb[i].offs = offs;
#if HAVE_LITTLE_ENDIAN
mtft->shift = bits_alloc;