Also make the case when one side in ?: is a ptr and the other is neither a ptr nor a null-ptr constant fail cleanly instead of segfaulting.
Unified · Split
| @@ -5598,7 +5598,9 @@ static void expr_cond(void) · 5597 unmodified lines | |||
| 5598 | 5598 | ||
| 5599 | 5599 | ||
| 5600 | /* cast operands to correct type according to ISOC rules */ | 5600 | /* cast operands to correct type according to ISOC rules */ |
| 5601 | if (is_float(bt1) || is_float(bt2)) { | 5601 | if (bt1 == VT_VOID || bt2 == VT_VOID) { |
| 5602 | type.t = VT_VOID; /* NOTE: as an extension, we accept void on only one side */ | ||
| 5603 | }else if (is_float(bt1) || is_float(bt2)) { | ||
| 5602 | if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) { | 5604 | if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) { |
| 5603 | type.t = VT_LDOUBLE; | 5605 | type.t = VT_LDOUBLE; |
| 5604 | 5606 | ||
| @@ -5625,8 +5627,11 @@ static void expr_cond(void) · 20 unmodified lines | |||
| 5625 | if (is_null_pointer (vtop)) type = type1; | 5627 | if (is_null_pointer (vtop)) type = type1; |
| 5626 | else if (is_null_pointer (&sv)) type = type2; | 5628 | else if (is_null_pointer (&sv)) type = type2; |
| 5627 | else{ | 5629 | else{ |
| 5628 | int pbt1 = (pointed_type(&type1)->t&VT_BTYPE); | 5630 | int pbt1, pbt2; |
| 5629 | int pbt2 = (pointed_type(&type2)->t&VT_BTYPE); | 5631 | if (bt1!=bt2) |
| 5632 | tcc_error("incompatible types in conditional expressions"); | ||
| 5633 | pbt1 = (pointed_type(&type1)->t&VT_BTYPE); | ||
| 5634 | pbt2 = (pointed_type(&type2)->t&VT_BTYPE); | ||
| 5630 | /*pointers to void get preferred, otherwise the pointed to types minus qualifs should be compatible*/ | 5635 | /*pointers to void get preferred, otherwise the pointed to types minus qualifs should be compatible*/ |
| 5631 | type = (pbt1==VT_VOID) ? type1 : type2; | 5636 | type = (pbt1==VT_VOID) ? type1 : type2; |
| 5632 | if (pbt1!=VT_VOID && pbt2!=VT_VOID){ | 5637 | if (pbt1!=VT_VOID && pbt2!=VT_VOID){ |
| @@ -5652,9 +5657,6 @@ static void expr_cond(void) · 19 unmodified lines | |||
| 5652 | } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { | 5657 | } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { |
| 5653 | /* XXX: test structure compatibility */ | 5658 | /* XXX: test structure compatibility */ |
| 5654 | type = bt1 == VT_STRUCT ? type1 : type2; | 5659 | type = bt1 == VT_STRUCT ? type1 : type2; |
| 5655 | } else if (bt1 == VT_VOID || bt2 == VT_VOID) { | ||
| 5656 | /* NOTE: as an extension, we accept void on only one side */ | ||
| 5657 | type.t = VT_VOID; | ||
| 5658 | } else { | 5660 | } else { |
| 5659 | /* integer operations */ | 5661 | /* integer operations */ |
| 5660 | type.t = VT_INT | (VT_LONG & (t1 | t2)); | 5662 | type.t = VT_INT | (VT_LONG & (t1 | t2)); |
| @@ -6,20 +6,24 @@ static void f (void){} · 5 unmodified lines | |||
| 6 | void (*fp)(void) = f; | 6 | void (*fp)(void) = f; |
| 7 | void call_fp() | 7 | void call_fp() |
| 8 | { | 8 | { |
| 9 | (fp?f:f)(); | 9 | (fp?f:f)(); |
| 10 | (fp?fp:fp)(); | 10 | (fp?fp:fp)(); |
| 11 | (fp?fp:&f)(); | 11 | (fp?fp:&f)(); |
| 12 | (fp?&f:fp)(); | 12 | (fp?&f:fp)(); |
| 13 | (fp?&f:&f)(); | 13 | (fp?&f:&f)(); |
| 14 | _Generic(0?arr:arr, char*: (void)0); | 14 | _Generic(0?arr:arr, char*: (void)0); |
| 15 | _Generic(0?&arr[0]:arr, char*: (void)0); | 15 | _Generic(0?&arr[0]:arr, char*: (void)0); |
| 16 | _Generic(0?arr:&arr[0], char*: (void)0); | 16 | _Generic(0?arr:&arr[0], char*: (void)0); |
| 17 | _Generic(1?arr:arr, char*: (void)0); | 17 | _Generic(1?arr:arr, char*: (void)0); |
| 18 | _Generic(1?&arr[0]:arr, char*: (void)0); | 18 | _Generic(1?&arr[0]:arr, char*: (void)0); |
| 19 | _Generic(1?arr:&arr[0], char*: (void)0); | 19 | _Generic(1?arr:&arr[0], char*: (void)0); |
| 20 | _Generic((__typeof(1?f:f)*){0}, void (**)(void): (void)0); | 20 | _Generic((__typeof(1?f:f)*){0}, void (**)(void): (void)0); |
| 21 | (fp?&f:f)(); | 21 | (fp?&f:f)(); |
| 22 | (fp?f:&f)(); | 22 | (fp?f:&f)(); |
| 23 | _Generic((__typeof(fp?0L:(void)0)*){0}, void*: (void)0); | ||
| 24 | |||
| 25 | //Should cleanly fail, not segfault: | ||
| 26 | /*(fp?f:1);*/ | ||
| 23 | } | 27 | } |
| 24 | 28 | ||
| 25 | int main() | 29 | int main() |