Hi, Sergey thanks for the patch! LGTM On 03.06.2024 17:34, Sergey Kaplun wrote: > From: Mike Pall > > (cherry picked from commit 899093a9e0fa5b16f27016381ef4b15529dadff2) > > According to C++ Standard, the `alignof()` (5.3.6.3) [1] and `sizeof()` > (5.3.3.2) [2] for the reference should be the same as for the referenced > type. This patch fixes the behaviour by following the reference to get a > child id for `alignof()` and `sizeof()` while parsing C definitions via > `ffi.cdef()`. > > Sergey Kaplun: > * added the description and the test for the problem > > Part of tarantool/tarantool#9924 > > [1]:https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4594.pdf#subsection.5.3.6 > [2]:https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4594.pdf#subsection.5.3.3 > --- > src/lj_cparse.c | 2 +- > .../lj-861-ctype-attributes.test.lua | 16 +++++++++++++++- > 2 files changed, 16 insertions(+), 2 deletions(-) > > diff --git a/src/lj_cparse.c b/src/lj_cparse.c > index 01deb3bf..8506d719 100644 > --- a/src/lj_cparse.c > +++ b/src/lj_cparse.c > @@ -468,7 +468,7 @@ static void cp_expr_sizeof(CPState *cp, CPValue *k, int wantsz) > } else { > cp_expr_unary(cp, k); > } > - info = lj_ctype_info(cp->cts, k->id, &sz); > + info = lj_ctype_info_raw(cp->cts, k->id, &sz); > if (wantsz) { > if (sz != CTSIZE_INVALID) > k->u32 = sz; > diff --git a/test/tarantool-tests/lj-861-ctype-attributes.test.lua b/test/tarantool-tests/lj-861-ctype-attributes.test.lua > index d88045a5..e8b29d67 100644 > --- a/test/tarantool-tests/lj-861-ctype-attributes.test.lua > +++ b/test/tarantool-tests/lj-861-ctype-attributes.test.lua > @@ -7,7 +7,7 @@ local tap = require('tap') > local test = tap.test('lj-861-ctype-attributes') > local ffi = require('ffi') > > -test:plan(2) > +test:plan(4) > > local EXPECTED_ALIGN = 4 > > @@ -15,6 +15,15 @@ ffi.cdef([[ > struct __attribute__((aligned($))) s_aligned { > uint8_t a; > }; > + > +struct test_parsing_sizeof { > + char a[sizeof(struct s_aligned &)]; > +}; > + > +struct test_parsing_alignof { > + char a[__alignof__(struct s_aligned &)]; > +}; > + > ]], EXPECTED_ALIGN) > > local ref_align = ffi.alignof(ffi.typeof('struct s_aligned &')) > @@ -23,4 +32,9 @@ test:is(ref_align, EXPECTED_ALIGN, 'the reference alignment is correct') > test:is(ref_align, ffi.alignof(ffi.typeof('struct s_aligned')), > 'the alignment of a reference is the same as for the referenced type') > > +test:is(ffi.sizeof('struct test_parsing_sizeof'), EXPECTED_ALIGN, > + 'correct sizeof during C parsing') > +test:is(ffi.sizeof('struct test_parsing_alignof'), EXPECTED_ALIGN, > + 'correct alignof during C parsing') > + > test:done(true)