mirror of
https://github.com/TinyCC/tinycc.git
synced 2026-02-04 04:41:37 +00:00
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:
22
tccpp.c
22
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;
|
||||
|
||||
Reference in New Issue
Block a user