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:
Michael Matz 2021-02-13 03:20:44 +01:00
parent 24c94fff09
commit d7f2775af8

View File

@ -1817,7 +1817,7 @@ static Sym *sym_copy(Sym *s0, Sym **ps)
static void sym_copy_ref(Sym *s, Sym **ps)
{
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;
for (s = *sp, *sp = NULL; s; s = s->next) {
Sym *s2 = sym_copy(s, ps);