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) 

Attachment: signature.asc
Description: This is a digitally signed message part.

_______________________________________________
Tinycc-devel mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to