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).
Unified · Split
| @@ -3179,10 +3179,8 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 3178 unmodified lines | ||
| 3179 | 3179 | |
| 3180 | 3180 | a = tok; /* save decl type */ |
| 3181 | 3181 | next(); |
| 3182 | − if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) { | |
| 3182 | + if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) | |
| 3183 | 3183 | parse_attribute(ad); |
| 3184 | − next(); | |
| 3185 | − } | |
| 3186 | 3184 | if (tok != '{') { |
| 3187 | 3185 | v = tok; |
| 3188 | 3186 | next(); |
| @@ -3302,7 +3300,7 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 113 unmodified lines | ||
| 3302 | 3300 | if (ad1.a.aligned) { |
| 3303 | 3301 | if (align < ad1.a.aligned) |
| 3304 | 3302 | align = ad1.a.aligned; |
| 3305 | − } else if (ad1.a.packed) { | |
| 3303 | + } else if (ad1.a.packed || ad->a.packed) { | |
| 3306 | 3304 | align = 1; |
| 3307 | 3305 | } else if (*tcc_state->pack_stack_ptr) { |
| 3308 | 3306 | if (align > *tcc_state->pack_stack_ptr) |
| @@ -108,6 +108,7 @@ void cmp_comparison_test(void); · 107 unmodified lines | ||
| 108 | 108 | void math_cmp_test(void); |
| 109 | 109 | void callsave_test(void); |
| 110 | 110 | void builtin_frame_address_test(void); |
| 111 | +void attrib_test(void); | |
| 111 | 112 | |
| 112 | 113 | int fib(int n); |
| 113 | 114 | void num(int n); |
| @@ -702,6 +703,7 @@ int main(int argc, char **argv) · 588 unmodified lines | ||
| 702 | 703 | intdiv_test(); |
| 703 | 704 | if (via_volatile (42) != 42) |
| 704 | 705 | printf ("via_volatile broken\n"); |
| 706 | + attrib_test(); | |
| 705 | 707 | return 0; |
| 706 | 708 | } |
| 707 | 709 | |
| @@ -2957,3 +2959,34 @@ char via_volatile (char i) · 2249 unmodified lines | ||
| 2957 | 2959 | vi = i; |
| 2958 | 2960 | return vi; |
| 2959 | 2961 | } |
| 2962 | + | |
| 2963 | +struct __attribute__((__packed__)) Spacked { | |
| 2964 | + char a; | |
| 2965 | + short b; | |
| 2966 | + int c; | |
| 2967 | +}; | |
| 2968 | +struct Spacked spacked; | |
| 2969 | +typedef struct __attribute__((__packed__)) { | |
| 2970 | + char a; | |
| 2971 | + short b; | |
| 2972 | + int c; | |
| 2973 | +} Spacked2; | |
| 2974 | +Spacked2 spacked2; | |
| 2975 | +#ifdef BROKEN | |
| 2976 | +/* This doesn't work for now. Requires adjusting field offsets/sizes | |
| 2977 | + after parsing the struct members. */ | |
| 2978 | +typedef struct Spacked3_s { | |
| 2979 | + char a; | |
| 2980 | + short b; | |
| 2981 | + int c; | |
| 2982 | +} __attribute__((__packed__)) Spacked3; | |
| 2983 | +Spacked3 spacked3; | |
| 2984 | +#endif | |
| 2985 | +void attrib_test(void) | |
| 2986 | +{ | |
| 2987 | + printf("attr: %d %d %d %d\n", sizeof(struct Spacked), | |
| 2988 | + sizeof(spacked), sizeof(Spacked2), sizeof(spacked2)); | |
| 2989 | +#ifdef BROKEN | |
| 2990 | + printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3)); | |
| 2991 | +#endif | |
| 2992 | +} | |