Package: tcc
Version: 0.9.26~git20120612.ad5f375-5
Severity: important
Tags: patch upstream

On i386 tcc can fails to read a long long value. A simple test case
showing the problem:

long long int ll[] = { 1LL, 2LL };

int main (void)
{
   long long int lli;
   lli = 1LL;
   return ll[lli];
}

This program returns 0 instead of 2. This could cause programs compiled
with tcc on i386 to misbehave.

Best regards,

Thomas Preud'homme

-- System Information:
Debian Release: wheezy/sid
  APT prefers unstable
  APT policy: (990, 'unstable'), (500, 'stable-updates'), (500, 'testing'), 
(500, 'stable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.2.0-3-amd64 (SMP w/2 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages tcc depends on:
ii  dpkg          1.16.7
ii  install-info  4.13a.dfsg.1-10
ii  libc6         2.13-34

Versions of packages tcc recommends:
ii  libc6-dev [libc-dev]  2.13-34

tcc suggests no packages.

-- no debconf information
>From d1694f7d7e6d96f64d1330c9b43491b613272b1e Mon Sep 17 00:00:00 2001
From: Thomas Preud'homme <[email protected]>
Date: Wed, 11 Jul 2012 23:39:05 +0200
Subject: [PATCH] get_reg(): try to free r2 for an SValue first

To be able to load a long long value correctly on i386, gv() rely on the
fact that when get_reg() look at an SValue it tries first to free the
register in r2 and then r. More information about the context can be
found at
http://lists.nongnu.org/archive/html/tinycc-devel/2012-06/msg00017.html
and later at
http://lists.nongnu.org/archive/html/tinycc-devel/2012-07/msg00021.html
---
 tccgen.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/tccgen.c b/tccgen.c
index d27bdba..71d0809 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -589,11 +589,11 @@ ST_FUNC int get_reg(int rc)
        IMPORTANT to start from the bottom to ensure that we don't
        spill registers used in gen_opi()) */
     for(p=vstack;p<=vtop;p++) {
-        r = p->r & VT_VALMASK;
+        /* look at second register (if long long) */
+        r = p->r2 & VT_VALMASK;
         if (r < VT_CONST && (reg_classes[r] & rc))
             goto save_found;
-        /* also look at second register (if long long) */
-        r = p->r2 & VT_VALMASK;
+        r = p->r & VT_VALMASK;
         if (r < VT_CONST && (reg_classes[r] & rc)) {
         save_found:
             save_reg(r);
@@ -812,7 +812,8 @@ ST_FUNC int gv(int rc)
                     vtop[-1].r = r; /* save register value */
                     vtop->r = vtop[-1].r2;
                 }
-                /* allocate second register */
+                /* Allocate second register. Here we rely on the fact that
+                   get_reg() tries first to free r2 of an SValue. */
                 r2 = get_reg(rc2);
                 load(r2, vtop);
                 vpop();
-- 
1.7.10.4

Reply via email to