Always allow ({ }) in the ctrl-expr of _Generic

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);`)
This commit is contained in:
Petr Skocik 2018-11-13 12:51:16 +01:00
parent 1e2e5671f7
commit f85b1e393f
2 changed files with 6 additions and 0 deletions

View File

@ -5033,13 +5033,16 @@ ST_FUNC void unary(void)
int has_match = 0;
int learn = 0;
TokenString *str = NULL;
int saved_const_wanted = const_wanted;
next();
skip('(');
const_wanted = 0;
expr_type(&controlling_type, expr_eq);
controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY);
if ((controlling_type.t & VT_BTYPE) == VT_FUNC)
mk_pointer(&controlling_type);
const_wanted = saved_const_wanted;
for (;;) {
learn = 0;
skip(',');

View File

@ -71,5 +71,8 @@ int main()
(void)_Generic((int(*)[2]){0}, int(*)[2]:0, int(*)[4]:0); //shouldn't match twice
//should accept ({ }) in the controlling expr of _Generic even in const_wanted contexts
struct { _Bool x_0: _Generic(({0;}),default:1); } my_x;
return 0;
}