| @@ -2565,13 +2565,20 @@ static int compare_types(CType *type1, CType *type2, int unqualified) · 2564 unmodified lines |
| 2565 | t1 &= ~VT_DEFSIGN; | 2565 | t1 &= ~VT_DEFSIGN; |
| 2566 | t2 &= ~VT_DEFSIGN; | 2566 | t2 &= ~VT_DEFSIGN; |
| 2567 | } | 2567 | } |
| | 2568 | /* An enum is compatible with (unsigned) int. Ideally we would |
| | 2569 | store the enums signedness in type->ref.a.<some_bit> and |
| | 2570 | only accept unsigned enums with unsigned int and vice versa. |
| | 2571 | But one of our callers (gen_assign_cast) always strips VT_UNSIGNED |
| | 2572 | from pointer target types, so we can't add it here either. */ |
| 2568 | if ((t1 & VT_BTYPE) == VT_ENUM) { | 2573 | if ((t1 & VT_BTYPE) == VT_ENUM) { |
| 2569 | /* An enum is compatible with (unsigned) int. */ | 2574 | t1 = VT_INT; |
| 2570 | t1 = VT_INT | (t1 & ~VT_BTYPE); | 2575 | if (type1->ref->a.unsigned_enum) |
| | 2576 | t1 |= VT_UNSIGNED; |
| 2571 | } | 2577 | } |
| 2572 | if ((t2 & VT_BTYPE) == VT_ENUM) { | 2578 | if ((t2 & VT_BTYPE) == VT_ENUM) { |
| 2573 | /* An enum is compatible with (unsigned) int. */ | 2579 | t2 = VT_INT; |
| 2574 | t2 = VT_INT | (t2 & ~VT_BTYPE); | 2580 | if (type2->ref->a.unsigned_enum) |
| | 2581 | t2 |= VT_UNSIGNED; |
| 2575 | } | 2582 | } |
| 2576 | /* XXX: bitfields ? */ | 2583 | /* XXX: bitfields ? */ |
| 2577 | if (t1 != t2) | 2584 | if (t1 != t2) |
| @@ -2766,15 +2773,23 @@ static void gen_assign_cast(CType *dt) · 188 unmodified lines |
| 2766 | (type2->t & VT_BTYPE) == VT_VOID) { | 2773 | (type2->t & VT_BTYPE) == VT_VOID) { |
| 2767 | /* void * can match anything */ | 2774 | /* void * can match anything */ |
| 2768 | } else { | 2775 | } else { |
| 2769 | /* exact type match, except for unsigned */ | 2776 | /* exact type match, except for qualifiers */ |
| 2770 | tmp_type1 = *type1; | 2777 | tmp_type1 = *type1; |
| 2771 | tmp_type2 = *type2; | 2778 | tmp_type2 = *type2; |
| 2772 | tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | | 2779 | tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE); |
| 2773 | VT_VOLATILE); | 2780 | tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE); |
| 2774 | tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | | 2781 | if (!is_compatible_types(&tmp_type1, &tmp_type2)) { |
| 2775 | VT_VOLATILE); | 2782 | /* Like GCC don't warn by default for merely changes |
| 2776 | if (!is_compatible_types(&tmp_type1, &tmp_type2)) | 2783 | in pointer target signedness. Do warn for different |
| 2777 | tcc_warning("assignment from incompatible pointer type"); | 2784 | base types, though, in particular for unsigned enums |
| | 2785 | and signed int targets. */ |
| | 2786 | if ((tmp_type1.t & (VT_DEFSIGN | VT_UNSIGNED)) != |
| | 2787 | (tmp_type2.t & (VT_DEFSIGN | VT_UNSIGNED)) && |
| | 2788 | (tmp_type1.t & VT_BTYPE) == (tmp_type2.t & VT_BTYPE)) |
| | 2789 | ; |
| | 2790 | else |
| | 2791 | tcc_warning("assignment from incompatible pointer type"); |
| | 2792 | } |
| 2778 | } | 2793 | } |
| 2779 | /* check const and volatile */ | 2794 | /* check const and volatile */ |
| 2780 | if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) || | 2795 | if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) || |
| @@ -3252,6 +3267,7 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 471 unmodified lines |
| 3252 | c = 0; | 3267 | c = 0; |
| 3253 | /* non empty enums are not allowed */ | 3268 | /* non empty enums are not allowed */ |
| 3254 | if (a == TOK_ENUM) { | 3269 | if (a == TOK_ENUM) { |
| | 3270 | int seen_neg = 0; |
| 3255 | for(;;) { | 3271 | for(;;) { |
| 3256 | v = tok; | 3272 | v = tok; |
| 3257 | if (v < TOK_UIDENT) | 3273 | if (v < TOK_UIDENT) |
| @@ -3265,6 +3281,8 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 7 unmodified lines |
| 3265 | next(); | 3281 | next(); |
| 3266 | c = expr_const(); | 3282 | c = expr_const(); |
| 3267 | } | 3283 | } |
| | 3284 | if (c < 0) |
| | 3285 | seen_neg = 1; |
| 3268 | /* enum symbols have static storage */ | 3286 | /* enum symbols have static storage */ |
| 3269 | ss = sym_push(v, &int_type, VT_CONST, c); | 3287 | ss = sym_push(v, &int_type, VT_CONST, c); |
| 3270 | ss->type.t |= VT_STATIC; | 3288 | ss->type.t |= VT_STATIC; |
| @@ -3276,6 +3294,8 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 5 unmodified lines |
| 3276 | if (tok == '}') | 3294 | if (tok == '}') |
| 3277 | break; | 3295 | break; |
| 3278 | } | 3296 | } |
| | 3297 | if (!seen_neg) |
| | 3298 | s->a.unsigned_enum = 1; |
| 3279 | s->c = type_size(&int_type, &align); | 3299 | s->c = type_size(&int_type, &align); |
| 3280 | skip('}'); | 3300 | skip('}'); |
| 3281 | } else { | 3301 | } else { |