Skip to content

Commit 829c848

Browse files
author
Stefan
committed
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.
1 parent cb41cbf commit 829c848

1 file changed

Lines changed: 15 additions & 7 deletions

File tree

tccpp.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2550,7 +2550,7 @@ static void parse_number(const char *p)
25502550
}
25512551
}
25522552
} else {
2553-
unsigned long long n, n1;
2553+
unsigned long long n = 0, n1 = 0;
25542554
int lcount, ucount, ov = 0;
25552555
const char *p1;
25562556

@@ -2561,7 +2561,6 @@ static void parse_number(const char *p)
25612561
b = 8;
25622562
q++;
25632563
}
2564-
n = 0;
25652564
while(1) {
25662565
t = *q++;
25672566
/* no need for checks except for base 10 / 8 errors */
@@ -2575,13 +2574,22 @@ static void parse_number(const char *p)
25752574
t = t - '0';
25762575
if (t >= b)
25772576
tcc_error("invalid digit");
2578-
n1 = n;
25792577
n = n * b + t;
2580-
/* detect overflow */
2581-
if (n1 >= 0x1000000000000000ULL && n / b != n1)
2582-
ov = 1;
2578+
if (!ov)
2579+
/* detect overflow */
2580+
if (n1 >= 0x1000000000000000ULL && n / b != n1)
2581+
ov = 1;
2582+
else
2583+
n1 = n;
25832584
}
2584-
2585+
#ifdef TCC_CUT_ON_INTEGER_LITERAL_OVERFLOW
2586+
/* On integer literal overflow use the most significant digits before
2587+
the overflow happened. Effectively this cuts the 0x1000000000000000
2588+
from above down to 0x10000000 and allows to bootstrap tcc with 32 bit
2589+
arithmetic. */
2590+
if (ov)
2591+
n = n1;
2592+
#endif
25852593
/* Determine the characteristics (unsigned and/or 64bit) the type of
25862594
the constant must have according to the constant suffix(es) */
25872595
lcount = ucount = 0;

0 commit comments

Comments
 (0)