(cond ? 0 : ptr)->member wasn't handled correctly. If one arm is a null pointer constant (which also can be a pointer) the result type is that of the other arm.
Unified · Split
| @@ -1489,7 +1489,8 @@ static inline int is_null_pointer(SValue *p) · 1488 unmodified lines | |||
| 1489 | if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) | 1489 | if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST) |
| 1490 | return 0; | 1490 | return 0; |
| 1491 | return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) || | 1491 | return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) || |
| 1492 | ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0); | 1492 | ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) || |
| 1493 | ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr == 0); | ||
| 1493 | } | 1494 | } |
| 1494 | 1495 | ||
| 1495 | static inline int is_integer_btype(int bt) | 1496 | static inline int is_integer_btype(int bt) |
| @@ -4116,14 +4117,22 @@ static void expr_cond(void) · 2620 unmodified lines | |||
| 4116 | (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED)) | 4117 | (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED)) |
| 4117 | type.t |= VT_UNSIGNED; | 4118 | type.t |= VT_UNSIGNED; |
| 4118 | } else if (bt1 == VT_PTR || bt2 == VT_PTR) { | 4119 | } else if (bt1 == VT_PTR || bt2 == VT_PTR) { |
| 4119 | /* XXX: test pointer compatibility */ | 4120 | /* If one is a null ptr constant the result type |
| 4120 | type = type1; | 4121 | is the other. */ |
| 4122 | if (is_null_pointer (vtop)) | ||
| 4123 | type = type1; | ||
| 4124 | else if (is_null_pointer (&sv)) | ||
| 4125 | type = type2; | ||
| 4126 | /* XXX: test pointer compatibility, C99 has more elaborate | ||
| 4127 | rules here. */ | ||
| 4128 | else | ||
| 4129 | type = type1; | ||
| 4121 | } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) { | 4130 | } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) { |
| 4122 | /* XXX: test function pointer compatibility */ | 4131 | /* XXX: test function pointer compatibility */ |
| 4123 | type = type1; | 4132 | type = bt1 == VT_FUNC ? type1 : type2; |
| 4124 | } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { | 4133 | } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { |
| 4125 | /* XXX: test structure compatibility */ | 4134 | /* XXX: test structure compatibility */ |
| 4126 | type = type1; | 4135 | type = bt1 == VT_STRUCT ? type1 : type2; |
| 4127 | } else if (bt1 == VT_VOID || bt2 == VT_VOID) { | 4136 | } else if (bt1 == VT_VOID || bt2 == VT_VOID) { |
| 4128 | /* NOTE: as an extension, we accept void on only one side */ | 4137 | /* NOTE: as an extension, we accept void on only one side */ |
| 4129 | type.t = VT_VOID; | 4138 | type.t = VT_VOID; |
| @@ -2486,3 +2486,16 @@ void const_warn_test(void) · 2485 unmodified lines | |||
| 2486 | { | 2486 | { |
| 2487 | const_func(1); | 2487 | const_func(1); |
| 2488 | } | 2488 | } |
| 2489 | |||
| 2490 | struct condstruct { | ||
| 2491 | int i; | ||
| 2492 | }; | ||
| 2493 | |||
| 2494 | int getme (struct condstruct *s, int i) | ||
| 2495 | { | ||
| 2496 | int i1 = (i == 0 ? 0 : s)->i; | ||
| 2497 | int i2 = (i == 0 ? s : 0)->i; | ||
| 2498 | int i3 = (i == 0 ? (void*)0 : s)->i; | ||
| 2499 | int i4 = (i == 0 ? s : (void*)0)->i; | ||
| 2500 | return i1 + i2 + i3 + i4; | ||
| 2501 | } | ||