mirror of
https://github.com/frida/tinycc
synced 2024-11-28 02:29:38 +03:00
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]
This commit is contained in:
parent
f0a25ca263
commit
d6d3cf00ec
24
tccgen.c
24
tccgen.c
@ -19,7 +19,6 @@
|
||||
*/
|
||||
|
||||
#include "tcc.h"
|
||||
|
||||
/********************************************************/
|
||||
/* global variables */
|
||||
|
||||
@ -2938,17 +2937,26 @@ static void type_to_str(char *buf, int buf_size,
|
||||
break;
|
||||
case VT_FUNC:
|
||||
s = type->ref;
|
||||
type_to_str(buf, buf_size, &s->type, varstr);
|
||||
pstrcat(buf, buf_size, "(");
|
||||
buf1[0]=0;
|
||||
if (varstr && '*' == *varstr) {
|
||||
pstrcat(buf1, sizeof(buf1), "(");
|
||||
pstrcat(buf1, sizeof(buf1), varstr);
|
||||
pstrcat(buf1, sizeof(buf1), ")");
|
||||
}
|
||||
pstrcat(buf1, buf_size, "(");
|
||||
sa = s->next;
|
||||
while (sa != NULL) {
|
||||
type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
|
||||
pstrcat(buf, buf_size, buf1);
|
||||
char buf2[256];
|
||||
type_to_str(buf2, sizeof(buf2), &sa->type, NULL);
|
||||
pstrcat(buf1, sizeof(buf1), buf2);
|
||||
sa = sa->next;
|
||||
if (sa)
|
||||
pstrcat(buf, buf_size, ", ");
|
||||
pstrcat(buf1, sizeof(buf1), ", ");
|
||||
}
|
||||
pstrcat(buf, buf_size, ")");
|
||||
if (s->f.func_type == FUNC_ELLIPSIS)
|
||||
pstrcat(buf1, sizeof(buf1), ", ...");
|
||||
pstrcat(buf1, sizeof(buf1), ")");
|
||||
type_to_str(buf, buf_size, &s->type, buf1);
|
||||
goto no_var;
|
||||
case VT_PTR:
|
||||
s = type->ref;
|
||||
@ -5005,6 +5013,8 @@ ST_FUNC void unary(void)
|
||||
skip('(');
|
||||
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);
|
||||
for (;;) {
|
||||
learn = 0;
|
||||
skip(',');
|
||||
|
@ -20,6 +20,12 @@ int b_f()
|
||||
return 10;
|
||||
}
|
||||
|
||||
typedef int (*fptr)(int);
|
||||
int foo(int i)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
typedef int int_type1;
|
||||
|
||||
#define gen_sw(a) _Generic(a, const char *: 1, default: 8, int: 123);
|
||||
@ -60,5 +66,7 @@ int main()
|
||||
long long: "long long"));
|
||||
i = _Generic(l, long: 1, int: 2);
|
||||
printf("%d\n", i);
|
||||
i = _Generic(foo, fptr: 3, int: 4);
|
||||
printf("%d\n", i);
|
||||
return 0;
|
||||
}
|
||||
|
@ -10,4 +10,5 @@
|
||||
3
|
||||
4
|
||||
long
|
||||
1
|
||||
1
|
||||
3
|
||||
|
Loading…
Reference in New Issue
Block a user