tcc would reject e.g., void f(){ struct {_Bool x:_Generic(({0;}),default:1);} my_x; } with `expected constant`. This patch makes it accept it. (The patch also makes tcc's _Generic a little more "generic" than that of gcc and clang in that that tcc now also accepts `struct {_Bool x:_Generic(({0;}),default:1);} my_x;` in file scope while gcc and clang don't, but I think there's no harm in that and gcc and clang might as well accept it in filescope too, given that they have no problem with e.g., `/*filescope:*/int x=1, y=2, z=_Generic(x+y, int:3);`)
Unified · Split
| @@ -5033,13 +5033,16 @@ ST_FUNC void unary(void) · 5032 unmodified lines | |||
| 5033 | int has_match = 0; | 5033 | int has_match = 0; |
| 5034 | int learn = 0; | 5034 | int learn = 0; |
| 5035 | TokenString *str = NULL; | 5035 | TokenString *str = NULL; |
| 5036 | int saved_const_wanted = const_wanted; | ||
| 5036 | 5037 | ||
| 5037 | next(); | 5038 | next(); |
| 5038 | skip('('); | 5039 | skip('('); |
| 5040 | const_wanted = 0; | ||
| 5039 | expr_type(&controlling_type, expr_eq); | 5041 | expr_type(&controlling_type, expr_eq); |
| 5040 | controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY); | 5042 | controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY); |
| 5041 | if ((controlling_type.t & VT_BTYPE) == VT_FUNC) | 5043 | if ((controlling_type.t & VT_BTYPE) == VT_FUNC) |
| 5042 | mk_pointer(&controlling_type); | 5044 | mk_pointer(&controlling_type); |
| 5045 | const_wanted = saved_const_wanted; | ||
| 5043 | for (;;) { | 5046 | for (;;) { |
| 5044 | learn = 0; | 5047 | learn = 0; |
| 5045 | skip(','); | 5048 | skip(','); |
| @@ -71,5 +71,8 @@ int main() · 70 unmodified lines | |||
| 71 | 71 | ||
| 72 | (void)_Generic((int(*)[2]){0}, int(*)[2]:0, int(*)[4]:0); //shouldn't match twice | 72 | (void)_Generic((int(*)[2]){0}, int(*)[2]:0, int(*)[4]:0); //shouldn't match twice |
| 73 | 73 | ||
| 74 | //should accept ({ }) in the controlling expr of _Generic even in const_wanted contexts | ||
| 75 | struct { _Bool x_0: _Generic(({0;}),default:1); } my_x; | ||
| 76 | |||
| 74 | return 0; | 77 | return 0; |
| 75 | } | 78 | } |