changeset 474:254e8668fb9d

Another fix from Joshua Phillips, for casting between pointers to integers of different sizes.
author Rob Landley <rob@landley.net>
date Wed, 05 Sep 2007 17:59:54 -0500
parents ec2b47ce2530
children 91c4c7d64f5e
files tcc.c tests/tcctest.c
diffstat 2 files changed, 10 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/tcc.c	Wed Sep 05 17:47:17 2007 -0500
+++ b/tcc.c	Wed Sep 05 17:59:54 2007 -0500
@@ -5135,6 +5135,11 @@
                the lvalue already contains the real type size (see
                VT_LVAL_xxx constants) */
         }
+    } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
+        /* if we are casting between pointer types,
+           we must update the VT_LVAL_xxx size */
+        vtop->r = (vtop->r & ~VT_LVAL_TYPE)
+                  | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
     }
     vtop->type = *type;
 }
--- a/tests/tcctest.c	Wed Sep 05 17:47:17 2007 -0500
+++ b/tests/tcctest.c	Wed Sep 05 17:59:54 2007 -0500
@@ -1149,6 +1149,7 @@
     unsigned b,d;
     short s;
     double g = 0.1;
+    char *data = "\x34\x34\x12";
 
     printf("cast_test:\n");
     a = 0xfffff;
@@ -1211,6 +1212,10 @@
     printf("0x%x == 0xfffff000\n", a);
     a = (signed char)0xf0f0;
     printf("0x%x == 0xfffffff0\n", a);
+
+    // Casting between pointers of different sizes.
+    s = *(short*)&data[1];
+    printf("0x%x == 0x1234 (or 0x3412)\n", s);
 }
 
 /* initializers tests */