like qualifier merging the array sizes are merged as well
for the operands of ?:, and they must not statically influence
the types of decls.
Also fix some style problems, spaces aren't stinky :)
char **argv;
_Generic(argv, char**: (void)0);
_Generic(0?(char const*)0:argv[0], char const*: (void)0);
_Generic(argv, char**: (void)0);
would fail because the type of argv would get modified by the
ternary. Now allocate a separate type on the value stack to
prevent this error.
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);`)
Code like:
#include <signal.h>
int main() { _Generic(signal, int: 0); }
should fail with
error: type 'extern void (*(int, void (*)(int)))(int)' does not match any association
not
error: type 'extern void *(int)(int, void *(int))' does not match any association
[matz: fix formatting, fix function-to-pointer decay for operands of
_Generic, add testcase for this]
* check that _Generic don't match unsigned char * with char *
this case is usefull as with -funsigned-char, 'char *' are unsigned
* change VT_LONG so it's now a qualifier
VT_LONG are never use for code generation, but only durring parsing state,
in _Generic we need to be able to make diference between
'long' and 'long long'
So VT_LONG is now use as a type qualifier, it's old behaviour is still
here, but we can keep trace of what was a long and what wasn't
* add TOK_CLONG and TOK_CULONG
tcc was directly converting value like '7171L' into TOK_CLLONG or
TOK_CINT depending of the machine architecture.
because of that, we was unable to make diference between a long and a
long long, which doesn't work with _Generic.
So now 7171L is a TOK_CLONG, and we can handle _Generic properly
* check that _Generic can make diference between long and long long
* uncomment "type match twice" as it should now pass tests on any platforms
* add inside_generic global
the point of this variable is to use VT_LONG in comparaison only
when we are evaluating a _Generic.
problem is with my lastest patchs tcc can now make the diference between
a 'long long' and a 'long', but in 64 bit stddef.h typedef uint64_t as
typedef signed long long int int64_t and stdint.h as unsigned long int, so tcc
break when stdint.h and stddef.h are include together.
Another solution woud be to modifie include/stddef.h so it define uint64_t as
unsigned long int when processor is 64 bit, but this could break some
legacy code, so for now, VT_LONG are use only inside generc.
* check that _Generic parse first argument correctly
* check that _Generic evaluate correctly exresion like "f() / 2"