Le samedi 9 juin 2012 15:57:03, [email protected] a écrit : > Hi list, > > Here is a simple C program that does not compile and execute correclty > with TCC (on i386, both with TCC 0.9.25 and with the latest sources; it > works on AMD64): > > #include <stdio.h> > > long long int ll[] = { 1LL, 2LL }; > unsigned long long int ull[] = { 1ULL, 2ULL }; > > int main () > { > long long int lli; > unsigned long long int ulli; > lli = 1LL; > printf ("%lld ", ll[lli]); printf ("%lld ", ll[1LL]); printf ("%lld\n", > ll[1]); printf ("%lld %lld %lld\n", ll[lli], ll[1LL], ll[1]); > if (ll[lli] == 2LL) printf ("OK "); else printf ("KO "); > if (ll[1LL] == 2LL) printf ("OK "); else printf ("KO "); > if (ll[1] == 2LL) printf ("OK\n"); else printf ("KO\n"); > ulli = 1ULL; > printf ("%llu ", ull[ulli]); printf ("%llu ", ull[1ULL]); printf > ("%llu\n", ull[1]); printf ("%llu %llu %llu\n", ull[ulli], ull[1ULL], > ull[1]); > if (ull[ulli] == 2ULL) printf ("OK "); else printf ("KO "); > if (ull[1ULL] == 2ULL) printf ("OK "); else printf ("KO "); > if (ull[1] == 2ULL) printf ("OK\n"); else printf ("KO\n"); > return 0; > } > > It should obviously print: > > 2 2 2 > 2 2 2 > OK OK OK > 2 2 2 > 2 2 2 > OK OK OK > > but it prints: > > 0 2 2 > 2 2 2 > KO OK OK > 0 2 2 > 2 2 2 > KO OK OK > > --ghe
Damn, there is at least 2 bugs there :(
I fixed a first one with the simple following test case:
long long int ll[] = { 1LL, 2LL };
int main ()
{
long long int lli;
lli = 1LL;
return ll[lli];
}
What happen is that in the gv(int rc) function, just after the comment
/* allocate second register */ the get_reg can causes the value loaded
previously into r to be saved onto the stack. The bug happen because at the
end of the function, just before the #ifdef TCC_TARGET_C67 vtop->r is set
again to r whereas the value is no longer in r.
Attached is a patch. It's not the best solution, but that's the first I found.
Improvement welcome.
Despite this, the following testcase still fails:
#include <stdio.h>
long long int ll[] = { 1LL, 2LL };
int main ()
{
long long int lli;
lli = 1LL;
printf ("%lld %lld\n", ll[lli], ll[1LL]);
printf ("%lld %lld\n", ll[lli], ll[lli]);
printf ("%lld\n", ll[lli]);
return 0;
}
I probably won't have time to look into it before quite some time so help
welcome to find the bug.
Best regards,
Thomas Preud'homme
>
> _______________________________________________
> Tinycc-devel mailing list
> [email protected]
> https://lists.nongnu.org/mailman/listinfo/tinycc-devel
diff --git a/tccgen.c b/tccgen.c
index d27bdba..57b3f7a 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -818,6 +818,7 @@ ST_FUNC int gv(int rc)
vpop();
/* write second register */
vtop->r2 = r2;
+ goto register_set;
} else
#endif
if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
@@ -843,6 +844,7 @@ ST_FUNC int gv(int rc)
}
}
vtop->r = r;
+register_set: ;
#ifdef TCC_TARGET_C67
/* uses register pairs for doubles */
if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Tinycc-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/tinycc-devel
