From 829c84852012426230b0bec0efcfc1609bf4665b Mon Sep 17 00:00:00 2001 From: Stefan Date: Sat, 13 Dec 2025 16:45:19 +0100 Subject: [PATCH] tccpp.c: Configurable integer literal overflow handling Add the define TCC_CUT_ON_INTEGER_LITERAL_OVERFLOW to use the most significant digits of an integer literal before its parsing led to an overflow. When compiling tcc with another compiler, which is not able to handle 64 bit arithmetic, it is beneficial to use the last value before an integer literal overflows. Parsing 0x1000000000000000 then results in 0x10000000. The mescc from GNU Mes is able to compile a first tcc on a 32 bit system without 64 bit arithmetic. This change allows this first tcc to compile a second tcc with complete 64 bit arithmetic. --- tccpp.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/tccpp.c b/tccpp.c index cd1ed9cc..cf5e69be 100644 --- a/tccpp.c +++ b/tccpp.c @@ -2550,7 +2550,7 @@ static void parse_number(const char *p) } } } else { - unsigned long long n, n1; + unsigned long long n = 0, n1 = 0; int lcount, ucount, ov = 0; const char *p1; @@ -2561,7 +2561,6 @@ static void parse_number(const char *p) b = 8; q++; } - n = 0; while(1) { t = *q++; /* no need for checks except for base 10 / 8 errors */ @@ -2575,13 +2574,22 @@ static void parse_number(const char *p) t = t - '0'; if (t >= b) tcc_error("invalid digit"); - n1 = n; n = n * b + t; - /* detect overflow */ - if (n1 >= 0x1000000000000000ULL && n / b != n1) - ov = 1; + if (!ov) + /* detect overflow */ + if (n1 >= 0x1000000000000000ULL && n / b != n1) + ov = 1; + else + n1 = n; } - +#ifdef TCC_CUT_ON_INTEGER_LITERAL_OVERFLOW + /* On integer literal overflow use the most significant digits before + the overflow happened. Effectively this cuts the 0x1000000000000000 + from above down to 0x10000000 and allows to bootstrap tcc with 32 bit + arithmetic. */ + if (ov) + n = n1; +#endif /* Determine the characteristics (unsigned and/or 64bit) the type of the constant must have according to the constant suffix(es) */ lcount = ucount = 0;