diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-05-18 08:10:50 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-05-18 08:10:50 -0700 |
commit | abcd7ee5c09d7fbd26410b6f880e5534b0bbb51a (patch) | |
tree | b8b754b8a5e38044892f785a13722ae750fdb487 /ffi.c | |
parent | e3f1adc4014641223ab3f5697e550439e10ddca8 (diff) | |
download | txr-abcd7ee5c09d7fbd26410b6f880e5534b0bbb51a.tar.gz txr-abcd7ee5c09d7fbd26410b6f880e5534b0bbb51a.tar.bz2 txr-abcd7ee5c09d7fbd26410b6f880e5534b0bbb51a.zip |
ffi: alignment bug in undimensioned arrays.
Because the varray behavior for undimensioned arrays was introduced
in dubious commit 7880c9b565ab438e1bf0250a967acdbf8d04cb42
in 2017, which used make_ffi_type_pointer to register the type,
claiming that the C representation is pointer (which was not true
in that commit, nor ever since).
As a result, though, undimensioned arrays received the alignment
of pointers, rather than deriving it from the element type.
Thus (array char) has 4 or 8 byte alignment whereas (array 4 char)
correctly has 1 byte alignment.
* ffi.c (ffi_type_compile): Use make_ffi_type_array for the two-element
array syntax, just like for the dimensioned case with three elements.
Then override some of the functions with the varray versions.
* tests/017/ffi-misc.tl: Fix the test case which exposed this.
In the type (struct flex (a char) (b (zarray char)), the array
b must be at offset 1. I didn't notice that the offset of 4
being confirmed by the test case was wrong, but this showed up
when running the test case on a platform with 8 byte pointers.
Diffstat (limited to 'ffi.c')
-rw-r--r-- | ffi.c | 14 |
1 files changed, 8 insertions, 6 deletions
@@ -3820,15 +3820,10 @@ val ffi_type_compile(val syntax) if (length(syntax) == two) { val eltype_syntax = cadr(syntax); val eltype = ffi_type_compile(eltype_syntax); - val type = make_ffi_type_pointer(syntax, vec_s, - ffi_varray_put, ffi_void_get, - ffi_varray_in, 0, ffi_varray_release, - eltype); + val type = make_ffi_type_array(syntax, vec_s, zero, eltype, self); struct txr_ffi_type *tft = ffi_type_struct(type); struct txr_ffi_type *etft = ffi_type_struct(eltype); - tft->kind = FFI_KIND_ARRAY; - if (etft->incomplete || etft->bitfield) uw_throwf(error_s, lit("~a: ~a ~s cannot be array element"), @@ -3836,6 +3831,13 @@ val ffi_type_compile(val syntax) if3(etft->bitfield, lit("bitfield"), lit("incomplete type")), eltype_syntax, nao); + + tft->put = ffi_varray_put; + tft->get = ffi_void_get; + tft->in = ffi_varray_in; + tft->out = 0; + tft->release = ffi_varray_release; + if (sym == zarray_s) { tft->null_term = 1; tft->get = ffi_varray_null_term_get; |