qbe

Internal scc patchset buffer for QBE
Log | Files | Refs | README | LICENSE

commit f3414a492bf4623731f3850aaae5b4a7a2a83a4d
parent 2bbfcf61b38edfe3c347cd270380e5117454c0cf
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue, 17 Aug 2021 15:18:00 +0200

parsefields: fix padding calculation

This was causing issues with aggregate types. A simple reproduction is:

type :type.1 = align 8 { 24 }
type :type.2 = align 8 { w 1, :type.1 1 }

The size of type.2 should be 32, adding only 4 bytes of padding between
the first and second field. Prior to this patch, 20 bytes of padding was
added instead, causing the type to have a size of 48.

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Mparse.c | 4++--
Atest/abi7.ssa | 21+++++++++++++++++++++
2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/parse.c b/parse.c @@ -867,9 +867,9 @@ parsefields(Field *fld, Typ *ty, int t) } if (a > al) al = a; - a = sz & (s-1); + a = (1 << a) - 1; + a = ((sz + a) & ~a) - sz; if (a) { - a = s - a; if (n < NField) { /* padding */ fld[n].type = FPad; diff --git a/test/abi7.ssa b/test/abi7.ssa @@ -0,0 +1,21 @@ +# test padding calculation with +# embedded struct + +type :s1 = align 4 { w 3 } +type :s2 = align 4 { b 1, :s1 1 } + +export function :s2 $test() { +@start + ret $s +} + +# >>> driver +# struct s2 { +# char x; +# struct { int a[3]; } s1; +# } s = { .x = 123 }; +# extern struct s2 test(void); +# int main(void) { +# return !(test().x == 123); +# } +# <<<