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.
This commit is contained in:
Stefan
2025-12-13 16:45:19 +01:00
parent cb41cbfe71
commit 829c848520

22
tccpp.c
View File

@@ -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;