tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] Mysterious tcc behavior: why does 0.0 takes 12 bytes when


From: David A. Wheeler
Subject: [Tinycc-devel] Mysterious tcc behavior: why does 0.0 takes 12 bytes when NOT long double?
Date: Thu, 26 May 2005 00:11:41 -0400
User-agent: Mozilla Thunderbird 1.0.2-1.3.2 (X11/20050324)

Here's an odd thing - I've noticed that tcc 0.9.22,
when compiling itself, writes _12_ bytes, not _8_,
for the "0.0" in its source code (the last 4 bytes look
like garbage). It does NOT do this
with a simple test case that just has 0.0 in it.

Why is this? Is this a symptom of something more serious?
Frankly, this looks like a bug of some kind.

Below are test cases so you can reproduce this strange behavior;
it looks like something isn't getting completely initialized/copied.

Thoughts?

--- David A. Wheeler


TEST 1:
First, here's a trivial program you can compile with tcc 0.9.22:

main() {
  printf("First");
  double a = 0.0;
  printf("Second");
}


If you "od -c" its results, at location 0001644 you see "First",
a \0 after First, another \0 padding to align the value,
eight 0x00 bytes for the double, and then string "Second"
results.  So here tcc saves 0.0 as an 8-byte double, which is
what I expected.


TEST 2:
Modify tcc as follows so you can this weirdness more directly:
--- tcc-0.9.22-float2/tcc.c     2004-11-08 15:47:16.000000000 -0500
+++ tcc-0.9.22-float/tcc.c      2005-05-25 22:52:56.000000000 -0400
@@ -3261,13 +3261,16 @@
                 ch = *p++;
                 tok = TOK_CFLOAT;
                 tokc.f = strtof(token_buf, NULL);
+                printf("\nDEBUG: type of %s is FLOAT\n", token_buf);
             } else if (t == 'L') {
                 ch = *p++;
                 tok = TOK_CLDOUBLE;
                 tokc.ld = strtold(token_buf, NULL);
+                printf("\nDEBUG: type of %s is LONG DOUBLE\n", token_buf);
             } else {
                 tok = TOK_CDOUBLE;
                 tokc.d = strtod(token_buf, NULL);
+                printf("\nDEBUG: type of %s is DOUBLE\n", token_buf);
             }
         }
     } else {
@@ -4652,10 +4655,13 @@
             offset = (data_section->data_offset + align - 1) & -align;
             data_section->data_offset = offset;
             /* XXX: not portable yet */
+ printf("DEBUG: Constant float in gv(), size=%d, offset=%lx, type=0x%x\n", size, offset,vtop->type.t);
             ptr = section_ptr_add(data_section, size);
             size = size >> 2;
-            for(i=0;i<size;i++)
+            for(i=0;i<size;i++) {
                 ptr[i] = vtop->c.tab[i];
+                printf("DEBUG: wrote ptr[%d]=0x%x\n", i, ptr[i]);
+            }
sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
             vtop->r |= VT_LVAL | VT_SYM;
             vtop->sym = sym;


Compile this with gcc, and then have the resulting
tcc compile itself; the first output
(a double writes two 4-byte words) makes sense, but the second
(a 0.0 double is written as three, not two, 4-byte words)
makes NO sense.  Here's the output:

DEBUG: type of 4294967296.0 is DOUBLE
DEBUG: Constant float in gv(), size=8, offset=1774, type=0x9
DEBUG: wrote ptr[0]=0x0
DEBUG: wrote ptr[1]=0x41f00000

DEBUG: type of 0.0 is DOUBLE
DEBUG: Constant float in gv(), size=12, offset=18e4, type=0xa
DEBUG: wrote ptr[0]=0x0
DEBUG: wrote ptr[1]=0x0
DEBUG: wrote ptr[2]=0xc90000


It's not that the value "0.0" is the kicker by itself;
compiling my trivial program above produces the expected results:

DEBUG: type of 0.0 is DOUBLE
DEBUG: Constant float in gv(), size=8, offset=c, type=0x9
DEBUG: wrote ptr[0]=0x0
DEBUG: wrote ptr[1]=0x0



Any ideas?





reply via email to

[Prev in Thread] Current Thread [Next in Thread]