Op 19-08-2025 om 23:32 schreef grischka:
On 19.08.2025 11:35, Herman ten Brugge via Tinycc-devel wrote:
This program stopped working after commit "local scope for types of
function parameters"
#include <stdio.h>
int main(void)
{
char c = 'a';
void func1(char c);
func1(c);
return 0;
}
void func1(char c)
{
printf("%c\n", c);
}
Oops, tricky. Thing is that if an 'extern' symbol or a function is
declared locally and is not yet known, then it is pushed on global_stack
via external_sym() and global_identifier_push().
But the 'ref' symbols (parameters) would be still on local_stack.
So these must be copied to global stack too otherwise it would crash
later when local stack was popped. This is done by copy_sym_ref().
It's just that these symbol must not be made lexically visible which
is what happened with this bug. Would just need to add in copy_sym():
You probably mean sym_copy 🙂
if ((s->v & ~SYM_STRUCT) < SYM_FIRST_ANOM
+ && ps == &local_stack)
sym_link(s, 1);
This indeed fixes the problem.
I have another nice problem:
int printf(const char *, ...);
struct st { int a; };
int main(void) {
struct st func(void), st;
st = func();
printf("%d\n", st.a);
}
struct st func(void) {
struct st st = { 10 };
return st;
}
When compiling this gives:
error: cannot convert 'struct st' to 'struct st'
I could fix this in compare_types by:
} else if (bt1 == VT_STRUCT) {
return (type1->ref->v == type2->ref->v);
I do not know if this is correct. Should this also be done for enums?
or should we create compare funcs for structs and enums?
Do to this change testcase 60 now fails so probably not the correct fix.
Found by running another test suite.
As to the debug problem:
I tested stabs and did 'p *s' in tcc.exe:main() to see TCCState,
nothing. So it turned out that because TCCState is typedef'd in
libtcc.h first, it is in stabs with no members and a size of -1
and won't be added later because it already was.
Dwarf seems to have another problem though that in a case with some
mutually linked structures, it would quickly eat up 2GB -> memory full.
Which is why I added -g1dwarf switch so I can compile that project.
Seems that stabs works because the tcc_debug_remove(s1, e); doesn't
work ('e' was never added). Whereas with dwarf 't' is removed but
the code never stops.
Why should it output the same structure more than once anyway ?
I debugged this and for stabs and dwarf it is used to register anon structs
(struct with no definition):
The is for example the case in __locale_t.h on my distrubution:
struct __locale_struct
{
struct __locale_data *__locales[13];
...
};
The __locale_data struct is never defined so I create a anon type for it.
If it is later defined I will replace this with the correct type in
dwarf code.
I cannot do this for stabs but still need to do this because otherwise I
create illegal stabs code.
If I compile tcc with your patch the stab is only 42 lines shorter
(0.03%) (objdump -G) because
no anons are output. The dwarf output is 259 lines shorter (0.03%)
(objdump -W).
I fix the anons at the end of the dwarf output with dummy types. This is
where the 0xffffffff
comes from when I do not do this.
So can you revert the patch?
Herman
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel