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 | a = tok; /* save decl type */ | 3180 | a = tok; /* save decl type */ |
| 3181 | next(); | 3181 | next(); |
| 3182 | if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) { | 3182 | if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) |
| 3183 | parse_attribute(ad); | 3183 | parse_attribute(ad); |
| 3184 | next(); | ||
| 3185 | } | ||
| 3186 | if (tok != '{') { | 3184 | if (tok != '{') { |
| 3187 | v = tok; | 3185 | v = tok; |
| 3188 | next(); | 3186 | next(); |
| @@ -3302,7 +3300,7 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 113 unmodified lines | |||
| 3302 | if (ad1.a.aligned) { | 3300 | if (ad1.a.aligned) { |
| 3303 | if (align < ad1.a.aligned) | 3301 | if (align < ad1.a.aligned) |
| 3304 | align = ad1.a.aligned; | 3302 | align = ad1.a.aligned; |
| 3305 | } else if (ad1.a.packed) { | 3303 | } else if (ad1.a.packed || ad->a.packed) { |
| 3306 | align = 1; | 3304 | align = 1; |
| 3307 | } else if (*tcc_state->pack_stack_ptr) { | 3305 | } else if (*tcc_state->pack_stack_ptr) { |
| 3308 | if (align > *tcc_state->pack_stack_ptr) | 3306 | if (align > *tcc_state->pack_stack_ptr) |
| @@ -108,6 +108,7 @@ void cmp_comparison_test(void); · 107 unmodified lines | |||
| 108 | void math_cmp_test(void); | 108 | void math_cmp_test(void); |
| 109 | void callsave_test(void); | 109 | void callsave_test(void); |
| 110 | void builtin_frame_address_test(void); | 110 | void builtin_frame_address_test(void); |
| 111 | void attrib_test(void); | ||
| 111 | 112 | ||
| 112 | int fib(int n); | 113 | int fib(int n); |
| 113 | void num(int n); | 114 | void num(int n); |
| @@ -702,6 +703,7 @@ int main(int argc, char **argv) · 588 unmodified lines | |||
| 702 | intdiv_test(); | 703 | intdiv_test(); |
| 703 | if (via_volatile (42) != 42) | 704 | if (via_volatile (42) != 42) |
| 704 | printf ("via_volatile broken\n"); | 705 | printf ("via_volatile broken\n"); |
| 706 | attrib_test(); | ||
| 705 | return 0; | 707 | return 0; |
| 706 | } | 708 | } |
| 707 | 709 | ||
| @@ -2957,3 +2959,34 @@ char via_volatile (char i) · 2249 unmodified lines | |||
| 2957 | vi = i; | 2959 | vi = i; |
| 2958 | return vi; | 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 | } | ||