From 7e14dde07b5fb5749b5f58fde3f24069682b3cc6 Mon Sep 17 00:00:00 2001 From: Greg King Date: Thu, 31 Dec 2015 17:41:48 -0500 Subject: [PATCH 1/2] Fixed the cc65 code that handled an addition of a pointer to a 32-bit offset. It didn't demote the offset to int because it looked at the pointer (instead of the offset) which already was 16 bits. --- src/cc65/expr.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 29e5771d4..34cf550a2 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -2390,7 +2390,6 @@ static void parseadd (ExprDesc* Expr) Type* lhst; /* Type of left hand side */ Type* rhst; /* Type of right hand side */ - /* Skip the PLUS token */ NextToken (); @@ -2573,7 +2572,7 @@ static void parseadd (ExprDesc* Expr) flags = CF_PTR; } else if (IsClassInt (lhst) && IsClassPtr (rhst)) { /* Left is int, right is pointer, must scale lhs */ - g_tosint (TypeOf (rhst)); /* Make sure, TOS is int */ + g_tosint (TypeOf (lhst)); /* Make sure TOS is int */ g_swap (CF_INT); /* Swap TOS and primary */ g_scale (CF_INT, CheckedPSizeOf (rhst)); /* Operate on pointers, result type is a pointer */ @@ -2607,7 +2606,6 @@ static void parseadd (ExprDesc* Expr) /* Condition codes not set */ ED_MarkAsUntested (Expr); - } From e0506557577bd26226bd5ef6fc1f9d5315207a99 Mon Sep 17 00:00:00 2001 From: Greg King Date: Fri, 1 Jan 2016 11:39:55 -0500 Subject: [PATCH 2/2] Added a cc65 regression test for pointer and offset addition operations. --- test/val/add5.c | 250 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 test/val/add5.c diff --git a/test/val/add5.c b/test/val/add5.c new file mode 100644 index 000000000..f8b7d669c --- /dev/null +++ b/test/val/add5.c @@ -0,0 +1,250 @@ +/* +** !!DESCRIPTION!! Simple tests about adding pointers and offsets +** !!ORIGIN!! cc65 regression tests +** !!LICENCE!! Public Domain +** !!AUTHOR!! 2016-01-01, Greg King +*/ + +#include + +static unsigned char failures = 0; + +static char array[16]; + +static char *cPtr; +static int *iPtr; +static long *lPtr; + +/* These functions test: adding an offset variable to a pointer variable. */ + +static void cPointer_char(void) +{ + char *cP = array; + char offset = 3; + + cPtr = cP + offset; + if (cPtr != (void *)&array[3]) { + ++failures; + } +} + +static void cPointer_int(void) +{ + char *cP = array; + int offset = 3; + + cPtr = cP + offset; + if (cPtr != (void *)&array[3]) { + ++failures; + } +} + +static void cPointer_long(void) +{ + char *cP = array; + long offset = 3; + + cPtr = cP + offset; + if (cPtr != (void *)&array[3]) { + ++failures; + } +} + +static void iPointer_char(void) +{ + int *iP = (int *)array; + char offset = 3; + + iPtr = iP + offset; + if (iPtr != (void *)&array[6]) { + ++failures; + } +} + +static void iPointer_int(void) +{ + int *iP = (int *)array; + int offset = 3; + + iPtr = iP + offset; + if (iPtr != (void *)&array[6]) { + ++failures; + } +} + +static void iPointer_long(void) +{ + int *iP = (int *)array; + long offset = 3; + + iPtr = iP + offset; + if (iPtr != (void *)&array[6]) { + ++failures; + } +} + +static void lPointer_char(void) +{ + long *lP = (long *)array; + char offset = 3; + + lPtr = lP + offset; + if (lPtr != (void *)&array[12]) { + ++failures; + } +} + +static void lPointer_int(void) +{ + long *lP = (long *)array; + int offset = 3; + + lPtr = lP + offset; + if (lPtr != (void *)&array[12]) { + ++failures; + } +} + +static void lPointer_long(void) +{ + long *lP = (long *)array; + long offset = 3; + + lPtr = lP + offset; + if (lPtr != (void *)&array[12]) { + ++failures; + } +} + +/* These functions test: adding a pointer variable to an offset variable. */ + +static void char_cPointer(void) +{ + char *cP = array; + char offset = 3; + + cPtr = offset + cP; + if (cPtr != (void *)&array[3]) { + ++failures; + } +} + +static void int_cPointer(void) +{ + char *cP = array; + int offset = 3; + + cPtr = offset + cP; + if (cPtr != (void *)&array[3]) { + ++failures; + } +} + +static void long_cPointer(void) +{ + char *cP = array; + long offset = 3; + + cPtr = (offset + cP); + if (cPtr != (void *)&array[3]) { + ++failures; + } +} + +static void char_iPointer(void) +{ + int *iP = (int *)array; + char offset = 3; + + iPtr = offset + iP; + if (iPtr != (void *)&array[6]) { + ++failures; + } +} + +static void int_iPointer(void) +{ + int *iP = (int *)array; + int offset = 3; + + iPtr = offset + iP; + if (iPtr != (void *)&array[6]) { + ++failures; + } +} + +static void long_iPointer(void) +{ + int *iP = (int *)array; + long offset = 3; + + iPtr = (offset + iP); + if (iPtr != (void *)&array[6]) { + ++failures; + } +} + +static void char_lPointer(void) +{ + long *lP = (long *)array; + char offset = 3; + + lPtr = offset + lP; + if (lPtr != (void *)&array[12]) { + ++failures; + } +} + +static void int_lPointer(void) +{ + long *lP = (long *)array; + int offset = 3; + + lPtr = offset + lP; + if (lPtr != (void *)&array[12]) { + ++failures; + } +} + +static void long_lPointer(void) +{ + long *lP = (long *)array; + long offset = 3; + + lPtr = (offset + lP); + if (lPtr != (void *)&array[12]) { + ++failures; + } +} + +int main(void) +{ + cPointer_char(); + cPointer_int(); + cPointer_long(); + + iPointer_char(); + iPointer_int(); + iPointer_long(); + + lPointer_char(); + lPointer_int(); + lPointer_long(); + + char_cPointer(); + int_cPointer(); + long_cPointer(); + + char_iPointer(); + int_iPointer(); + long_iPointer(); + + char_lPointer(); + int_lPointer(); + long_lPointer(); + + if (failures != 0) { + printf("add5: failures: %u\n", failures); + } + return failures; +}