| @@ -3062,6 +3062,24 @@ ST_FUNC void parse_mult_str (CString *astr, const char *msg) · 3061 unmodified lines |
| 3062 | cstr_ccat(astr, '\0'); | 3062 | cstr_ccat(astr, '\0'); |
| 3063 | } | 3063 | } |
| 3064 | | 3064 | |
| | 3065 | /* If I is >= 1 and a power of two, returns log2(i)+1. |
| | 3066 | If I is 0 returns 0. */ |
| | 3067 | static int exact_log2p1(int i) |
| | 3068 | { |
| | 3069 | int ret; |
| | 3070 | if (!i) |
| | 3071 | return 0; |
| | 3072 | for (ret = 1; i >= 1 << 8; ret += 8) |
| | 3073 | i >>= 8; |
| | 3074 | if (i >= 1 << 4) |
| | 3075 | ret += 4, i >>= 4; |
| | 3076 | if (i >= 1 << 2) |
| | 3077 | ret += 2, i >>= 2; |
| | 3078 | if (i >= 1 << 1) |
| | 3079 | ret++; |
| | 3080 | return ret; |
| | 3081 | } |
| | 3082 | |
| 3065 | /* Parse GNUC __attribute__ extension. Currently, the following | 3083 | /* Parse GNUC __attribute__ extension. Currently, the following |
| 3066 | extensions are recognized: | 3084 | extensions are recognized: |
| 3067 | - aligned(n) : set data/function alignment. | 3085 | - aligned(n) : set data/function alignment. |
| @@ -3131,7 +3149,9 @@ static void parse_attribute(AttributeDef *ad) · 63 unmodified lines |
| 3131 | } else { | 3149 | } else { |
| 3132 | n = MAX_ALIGN; | 3150 | n = MAX_ALIGN; |
| 3133 | } | 3151 | } |
| 3134 | ad->a.aligned = n; | 3152 | ad->a.aligned = exact_log2p1(n); |
| | 3153 | if (n != 1 << (ad->a.aligned - 1)) |
| | 3154 | tcc_error("alignment of %d is larger than implemented", n); |
| 3135 | break; | 3155 | break; |
| 3136 | case TOK_PACKED1: | 3156 | case TOK_PACKED1: |
| 3137 | case TOK_PACKED2: | 3157 | case TOK_PACKED2: |
| @@ -3270,7 +3290,7 @@ static void struct_layout(CType *type, AttributeDef *ad) · 132 unmodified lines |
| 3270 | int pcc = !tcc_state->ms_bitfields; | 3290 | int pcc = !tcc_state->ms_bitfields; |
| 3271 | Sym *f; | 3291 | Sym *f; |
| 3272 | if (ad->a.aligned) | 3292 | if (ad->a.aligned) |
| 3273 | maxalign = ad->a.aligned; | 3293 | maxalign = 1 << (ad->a.aligned - 1); |
| 3274 | else | 3294 | else |
| 3275 | maxalign = 1; | 3295 | maxalign = 1; |
| 3276 | offset = 0; | 3296 | offset = 0; |
| @@ -3293,6 +3313,8 @@ static void struct_layout(CType *type, AttributeDef *ad) · 16 unmodified lines |
| 3293 | align = f->r; | 3313 | align = f->r; |
| 3294 | } else if (ad->a.packed || f->r == 1) { | 3314 | } else if (ad->a.packed || f->r == 1) { |
| 3295 | align = 1; | 3315 | align = 1; |
| | 3316 | /* Packed fields or packed records don't let the base type |
| | 3317 | influence the records type alignment. */ |
| 3296 | typealign = 1; | 3318 | typealign = 1; |
| 3297 | } else { | 3319 | } else { |
| 3298 | align = typealign; | 3320 | align = typealign; |
| @@ -3587,8 +3609,9 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 288 unmodified lines |
| 3587 | /* Only remember non-default alignment. */ | 3609 | /* Only remember non-default alignment. */ |
| 3588 | alignoverride = 0; | 3610 | alignoverride = 0; |
| 3589 | if (ad1.a.aligned) { | 3611 | if (ad1.a.aligned) { |
| 3590 | if (align < ad1.a.aligned) | 3612 | int speca = 1 << (ad1.a.aligned - 1); |
| 3591 | alignoverride = ad1.a.aligned; | 3613 | if (align < speca) |
| | 3614 | alignoverride = speca; |
| 3592 | } else if (ad1.a.packed || ad->a.packed) { | 3615 | } else if (ad1.a.packed || ad->a.packed) { |
| 3593 | alignoverride = 1; | 3616 | alignoverride = 1; |
| 3594 | } else if (*tcc_state->pack_stack_ptr) { | 3617 | } else if (*tcc_state->pack_stack_ptr) { |
| @@ -6594,8 +6617,9 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 2999 unmodified lines |
| 6594 | * pointed_size(&flexible_array->type); | 6617 | * pointed_size(&flexible_array->type); |
| 6595 | /* take into account specified alignment if bigger */ | 6618 | /* take into account specified alignment if bigger */ |
| 6596 | if (ad->a.aligned) { | 6619 | if (ad->a.aligned) { |
| 6597 | if (ad->a.aligned > align) | 6620 | int speca = 1 << (ad->a.aligned - 1); |
| 6598 | align = ad->a.aligned; | 6621 | if (speca > align) |
| | 6622 | align = speca; |
| 6599 | } else if (ad->a.packed) { | 6623 | } else if (ad->a.packed) { |
| 6600 | align = 1; | 6624 | align = 1; |
| 6601 | } | 6625 | } |