summaryrefslogtreecommitdiffstats
path: root/ffi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-08-24 07:50:48 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-08-24 07:50:48 -0700
commit23d1d7e768e88dc9c8c511afcd2940bee562550a (patch)
tree8484afd2436836ea0343ca757194bdba12e0f723 /ffi.c
parent365c877d8b31653e12c5284266753671d6515774 (diff)
downloadtxr-23d1d7e768e88dc9c8c511afcd2940bee562550a.tar.gz
txr-23d1d7e768e88dc9c8c511afcd2940bee562550a.tar.bz2
txr-23d1d7e768e88dc9c8c511afcd2940bee562550a.zip
ffi: bugfix: zero-width bitfield offset problem.
* ffi.c (make_ffi_type_struct): Fix incorrect condition for determining whether the zero-width bitfield allocates a unit or not. We must take into account the bit_offs, because it's possible that unit_offs and offs are the same, yet a previous bitfield has allocated some bits into the current allocation unit. For instance struct { char a : 1; uint32 : 0; char b } has size 5, but the equivalent FFI struct type ends up with size 1. After char a : 1, the byte offset is still zero, so if we don't look at the bit offset of 1, it looks like the allocation offset is aligned to the start of a uint32 cell, which then means that the zero-width bitfield is ignored. What's worse, the char b is then also allocated over top of the a : 1 bitfield.
Diffstat (limited to 'ffi.c')
-rw-r--r--ffi.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/ffi.c b/ffi.c
index dd2fe20d..d8522d89 100644
--- a/ffi.c
+++ b/ffi.c
@@ -3295,7 +3295,7 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
ucnum room = bits_type - bits_alloc;
if (bits == 0) {
- if (offs != unit_offs)
+ if (offs != unit_offs || bit_offs > 0)
offs = unit_offs + size;
bit_offs = 0;
nmemb--, i--;