Fix endless recursion due to type scoping
this change fixes building of invalid types. The inner scope
struct P is return type of the forward decl foobar. The outer scope
foobar() call implicitely declares that function again, with int
return type; overall this leads to access within the sym free list,
effectively building up a type directly referring to itself, leading
to endless recursion later. The testcase is:
void n(void)
{
{
struct P {
int __val;
};
struct P foobar(); // 1
}
foobar(); // 2
}
I've not included it in tests2 for now, because tcc accepts this.
Ideally we would like to reject it (as 'int foobar();' is incompatible
with the earlier decl). clang also accepts it, but only because it's
not handling (1) above as an implicit decl of foobar (it warns, and
with -pedantic also warns about the type incompatiblity). GCC rejects
this.
Implementing that in tcc requires some surgery, as we need to differ
between these cases:
{ struct P foo(int); // 1
foo(); // no implicit decl, call to foo from 1
}
and
{ { struct P foo(int); // 2 }
foo(); // implicit decl, _incompatible_ with 2
}
This commit is contained in:
parent
24c94fff09
commit
d7f2775af8
1 changed files with 1 additions and 1 deletions
2
tccgen.c
2
tccgen.c
|
|
@ -1817,7 +1817,7 @@ static Sym *sym_copy(Sym *s0, Sym **ps)
|
||||||
static void sym_copy_ref(Sym *s, Sym **ps)
|
static void sym_copy_ref(Sym *s, Sym **ps)
|
||||||
{
|
{
|
||||||
int bt = s->type.t & VT_BTYPE;
|
int bt = s->type.t & VT_BTYPE;
|
||||||
if (bt == VT_FUNC || bt == VT_PTR) {
|
if (bt == VT_FUNC || bt == VT_PTR || (bt == VT_STRUCT && s->sym_scope)) {
|
||||||
Sym **sp = &s->type.ref;
|
Sym **sp = &s->type.ref;
|
||||||
for (s = *sp, *sp = NULL; s; s = s->next) {
|
for (s = *sp, *sp = NULL; s; s = s->next) {
|
||||||
Sym *s2 = sym_copy(s, ps);
|
Sym *s2 = sym_copy(s, ps);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue