From 49dfb5755adb04588366f02fa73ad566490ebdbb Mon Sep 17 00:00:00 2001 From: Petr Skocik Date: Thu, 29 Nov 2018 12:43:01 +0100 Subject: [PATCH] Make fn designators in ?: decay to ptrs This _Generic((__typeof(1?f:f)*){0}, void (**)(void): (void)0); should compile like it does in gcc and clang. --- tccgen.c | 13 ++++++++----- tests/tests2/33_ternary_op.c | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/tccgen.c b/tccgen.c index 0077769..e70c843 100644 --- a/tccgen.c +++ b/tccgen.c @@ -5565,7 +5565,10 @@ static void expr_cond(void) if (!g) gexpr(); - type1 = vtop->type; + if ( ((type1=vtop->type).t&VT_BTYPE)==VT_FUNC ) { + mk_pointer(&vtop->type); + type1=vtop->type; + } sv = *vtop; /* save value to handle it later */ vtop--; /* no vpop so that FP stack is not flushed */ skip(':'); @@ -5583,7 +5586,10 @@ static void expr_cond(void) if (c == 1) nocode_wanted--; - type2 = vtop->type; + if ( ((type2=vtop->type).t&VT_BTYPE)==VT_FUNC ) { + mk_pointer(&vtop->type); + type2=vtop->type; + } t1 = type1.t; bt1 = t1 & VT_BTYPE; t2 = type2.t; @@ -5643,9 +5649,6 @@ static void expr_cond(void) 0ref->c ? pointed_type(&type1)->ref->c : pointed_type(&type2)->ref->c; } - } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) { - /* XXX: test function pointer compatibility */ - type = bt1 == VT_FUNC ? type1 : type2; } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) { /* XXX: test structure compatibility */ type = bt1 == VT_STRUCT ? type1 : type2; diff --git a/tests/tests2/33_ternary_op.c b/tests/tests2/33_ternary_op.c index 33cda44..bf637d4 100644 --- a/tests/tests2/33_ternary_op.c +++ b/tests/tests2/33_ternary_op.c @@ -1,6 +1,27 @@ #include #include +char arr[1]; +static void f (void){} +void (*fp)(void) = f; +void call_fp() +{ + (fp?f:f)(); + (fp?fp:fp)(); + (fp?fp:&f)(); + (fp?&f:fp)(); + (fp?&f:&f)(); + _Generic(0?arr:arr, char*: (void)0); + _Generic(0?&arr[0]:arr, char*: (void)0); + _Generic(0?arr:&arr[0], char*: (void)0); + _Generic(1?arr:arr, char*: (void)0); + _Generic(1?&arr[0]:arr, char*: (void)0); + _Generic(1?arr:&arr[0], char*: (void)0); + _Generic((__typeof(1?f:f)*){0}, void (**)(void): (void)0); + (fp?&f:f)(); + (fp?f:&f)(); +} + int main() { int Count;