Commit Graph

13 Commits

Author SHA1 Message Date
herman ten brugge
c13bbb5cb5 Add type promotion in comma expression and update testcase 94 2024-01-06 07:54:34 +01:00
Michael Matz
aa9093a144 Fix null pointer constants
an expression like 'i*0', even though it's value is constant and
can be evaluated at compile time is not an integer constant expression,
and hence no null pointer constant, and therefore the conditional
operator doesn't select the other type.
2022-08-16 16:58:00 +02:00
Arthur Williams
3709f8de14 Treat func pointers with different return types as not compatible
Tcc considered function ptrs with different return types to be
compatible which disallowed some otherwise valid operations like:
`_Generic(foo, int(*)():0, void(*)(void):1)`
which would fail to compile with a error message of "type match twice"

This changed also required longjump's return type to be void and
munmap's to be int to be compatible with standard headers.
2020-11-22 16:30:34 -06:00
Michael Matz
c4787e3626 Fix type completion for array types as well
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 :)
2018-11-30 23:43:30 +01:00
Petr Skocik
9d44b02a49 Fix the fix on type combining (e0012c2)
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.
2018-11-29 10:26:35 +01:00
Petr Skocik
e0012c2767 Fix ptr type combining inside the ternary operator
Make it match http://port70.net/~nsz/c/c99/n1256.html#6.5.15p6
(or http://port70.net/~nsz/c/c11/n1570.html#6.5.15p6).
2018-11-28 10:36:58 +01:00
Petr Skocik
c81116e29a Make casts lose top-level qualifiers
TODO: also make them lose lvalue status
2018-11-20 19:24:24 +01:00
Petr Skocik
f85b1e393f 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);`)
2018-11-13 12:51:16 +01:00
Petr Skocik
314843ffc3 Fix how _Generic treats pointers to arrays.
_Generic should distinguish pointers to differently sized
arrays such as `int(*)[2]` and `int(*)[4]`.
2018-11-12 20:52:14 +01:00
Petr Skocik
d6d3cf00ec patch type_to_str to handle complex function-ptr decls better
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]
2018-04-01 00:38:11 +02:00
Matthias Gatto
23064b1734 check that _Generic match 'signed long int' as 'long' 2017-07-25 18:56:41 +02:00
matthias
fdc18d307a mutiples fix for _Generic
* 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"
2017-07-21 19:30:31 +02:00
Matthias Gatto
16d3dbf2d0 add _Generic test 2017-07-05 17:59:42 +02:00