diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index ec49d0e3c..f747fb458 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -39,6 +39,7 @@ #include #include #include +#include /* common */ #include "chartype.h" @@ -151,6 +152,11 @@ static const struct Keyword { #define IT_ULONG 0x08 +/* Internal type for numeric constant scanning. +** Size must be explicit for cross-platform uniformity. +*/ +typedef uint32_t scan_t; + /*****************************************************************************/ /* code */ @@ -521,7 +527,7 @@ static void NumericConst (void) int IsFloat; char C; unsigned DigitVal; - unsigned long IVal; /* Value */ + scan_t IVal; /* Scanned value. */ int Overflow; /* Get the pp-number first, then parse on it */ @@ -584,19 +590,19 @@ static void NumericConst (void) SB_Clear (&Src); break; } - if ((((unsigned long)(IVal * Base)) / Base) != IVal) { + if (((scan_t)(IVal * Base) / Base) != IVal) { Overflow = 1; } IVal = IVal * Base; - if (((unsigned long)(IVal + DigitVal)) < IVal) { + if (((scan_t)(IVal + DigitVal)) < IVal) { Overflow = 1; } IVal += DigitVal; SB_Skip (&Src); } if (Overflow) { - Error ("Numerical constant \"%s\" too large for internal 32-bit representation", - SB_GetConstBuf (&Src)); + Error ("Numerical constant \"%s\" too large for internal %d-bit representation", + SB_GetConstBuf (&Src), (int)(sizeof(IVal)*8)); } /* Distinguish between integer and floating point constants */ diff --git a/test/val/common.h b/test/val/common.h index dada61a14..61da6c325 100644 --- a/test/val/common.h +++ b/test/val/common.h @@ -20,3 +20,4 @@ #define SIZEOF_LONG_32BIT #define UNSIGNED_CHARS #define UNSIGNED_BITFIELDS +#define INTEGER_CONSTANT_MAX_32BIT diff --git a/test/val/cq241.c b/test/val/cq241.c index 611b5a376..a6d6c5324 100644 --- a/test/val/cq241.c +++ b/test/val/cq241.c @@ -4,6 +4,14 @@ !!LICENCE!! own, freely distributeable for non-profit. read CPYRIGHT.LCC */ +/* INTEGER_CONSTANT_MAX_32BIT +** This suppresses constants longer than 32-bit, which are now an error: +** https://github.com/cc65/cc65/pull/2084 +** Because cc65's internal representation is implicitly/explicitly +** 32-bit in many places, values larger than this aren't representable, +** but also can't be checked for overflow once accepted. +*/ + #include "common.h" struct defs { @@ -62,7 +70,12 @@ long pow2(long n) { return s; } - long d[39], o[39], x[39]; +#ifndef INTEGER_CONSTANT_MAX_32BIT +#define CTCOUNT 39 +#else +#define CTCOUNT 36 +#endif + long d[CTCOUNT], o[CTCOUNT], x[CTCOUNT]; #ifndef NO_OLD_FUNC_DECL s241(pd0) @@ -212,13 +225,15 @@ int s241(struct defs *pd0) { d[33] = 1073741823; o[33] = 07777777777; x[33] = 0x3fffffff; d[34] = 1073741824; o[34] = 010000000000; x[34] = 0x40000000; d[35] = 4294967295; o[35] = 037777777777; x[35] = 0xffffffff; +#if CTCOUNT > 36 d[36] = 4294967296; o[36] = 040000000000; x[36] = 0x100000000; d[37] = 68719476735; o[37] = 0777777777777; x[37] = 0xfffffffff; d[38] = 68719476736; o[38] = 01000000000000; x[38] = 0x1000000000; +#endif /* WHEW! */ - for (j=0; j<39; j++){ + for (j=0; j