From f85b1e393f9f32c04e9fa1e870d4ee759d2089e9 Mon Sep 17 00:00:00 2001 From: Petr Skocik Date: Tue, 13 Nov 2018 12:51:16 +0100 Subject: [PATCH] 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);`) --- tccgen.c | 3 +++ tests/tests2/94_generic.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/tccgen.c b/tccgen.c index 5b0c2a63..0d686961 100644 --- a/tccgen.c +++ b/tccgen.c @@ -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(','); diff --git a/tests/tests2/94_generic.c b/tests/tests2/94_generic.c index 6e20282c..e5df2a77 100644 --- a/tests/tests2/94_generic.c +++ b/tests/tests2/94_generic.c @@ -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; } -- 2.11.4.GIT