diff options
| author | Michael Matz <matz@suse.de> | 2016-07-11 18:38:00 +0200 |
|---|---|---|
| committer | Michael Matz <matz@suse.de> | 2016-12-15 17:47:08 +0100 |
| commit | 2b618c1ab4b9a4b8bd9c362cff070fa40cd03353 (patch) | |
| tree | 44e92b1b1b45f937656278baf2f3cb726ff147a1 | |
| parent | 7e515466246b30f02867fc1f1902dea706ff31af (diff) | |
| download | tinycc-2b618c1ab4b9a4b8bd9c362cff070fa40cd03353.tar.gz tinycc-2b618c1ab4b9a4b8bd9c362cff070fa40cd03353.tar.bz2 | |
Fix parsing attributes for struct decls
Given this code:
struct __attribute__((...)) Name {...};
TCC was eating "Name", hence generating an anonymous struct.
It also didn't apply any packed attributes to the parsed
members. Both fixed. The testcase also contains a case
that isn't yet handled by TCC (under a BROKEN #define).
| -rw-r--r-- | tccgen.c | 6 | ||||
| -rw-r--r-- | tests/tcctest.c | 33 |
2 files changed, 35 insertions, 4 deletions
@@ -3179,10 +3179,8 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) a = tok; /* save decl type */ next(); - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) { + if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) parse_attribute(ad); - next(); - } if (tok != '{') { v = tok; next(); @@ -3302,7 +3300,7 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) if (ad1.a.aligned) { if (align < ad1.a.aligned) align = ad1.a.aligned; - } else if (ad1.a.packed) { + } else if (ad1.a.packed || ad->a.packed) { align = 1; } else if (*tcc_state->pack_stack_ptr) { if (align > *tcc_state->pack_stack_ptr) diff --git a/tests/tcctest.c b/tests/tcctest.c index a6878db..57226f7 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -108,6 +108,7 @@ void cmp_comparison_test(void); void math_cmp_test(void); void callsave_test(void); void builtin_frame_address_test(void); +void attrib_test(void); int fib(int n); void num(int n); @@ -702,6 +703,7 @@ int main(int argc, char **argv) intdiv_test(); if (via_volatile (42) != 42) printf ("via_volatile broken\n"); + attrib_test(); return 0; } @@ -2957,3 +2959,34 @@ char via_volatile (char i) vi = i; return vi; } + +struct __attribute__((__packed__)) Spacked { + char a; + short b; + int c; +}; +struct Spacked spacked; +typedef struct __attribute__((__packed__)) { + char a; + short b; + int c; +} Spacked2; +Spacked2 spacked2; +#ifdef BROKEN +/* This doesn't work for now. Requires adjusting field offsets/sizes + after parsing the struct members. */ +typedef struct Spacked3_s { + char a; + short b; + int c; +} __attribute__((__packed__)) Spacked3; +Spacked3 spacked3; +#endif +void attrib_test(void) +{ + printf("attr: %d %d %d %d\n", sizeof(struct Spacked), + sizeof(spacked), sizeof(Spacked2), sizeof(spacked2)); +#ifdef BROKEN + printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3)); +#endif +} |
