diff options
author | Drew DeVault <sir@cmpwn.com> | 2021-08-17 15:18:00 +0200 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2021-08-23 10:03:13 +0200 |
commit | f3414a492bf4623731f3850aaae5b4a7a2a83a4d (patch) | |
tree | b2846c060327a421e5894527ca10225112daacf2 | |
parent | 2bbfcf61b38edfe3c347cd270380e5117454c0cf (diff) | |
download | roux-f3414a492bf4623731f3850aaae5b4a7a2a83a4d.tar.gz |
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>
-rw-r--r-- | parse.c | 4 | ||||
-rw-r--r-- | test/abi7.ssa | 21 |
2 files changed, 23 insertions, 2 deletions
diff --git a/parse.c b/parse.c index a7e4452..43ae23b 100644 --- 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 new file mode 100644 index 0000000..bf8ca1f --- /dev/null +++ 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); +# } +# <<< |