Skip to content

Commit b338126

Browse files
author
grischka
committed
pp-expression numbers always long long
Aka 'intmax_t', as recommended by newer standards. For example if (-0x80000000 < 0) is false, but #if (-0x80000000 < 0) is true because in C, 0x80000000 is an unsigned int, Whereas in a preprocessor expression, it is a signed long long, even without LL suffix.
1 parent f57cc34 commit b338126

File tree

3 files changed

+38
-10
lines changed

3 files changed

+38
-10
lines changed

tccpp.c

+10-10
Original file line numberDiff line numberDiff line change
@@ -542,11 +542,7 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv)
542542
case TOK_CLLONG:
543543
case TOK_CULLONG:
544544
/* XXX: not quite exact, but only useful for testing */
545-
#ifdef _WIN32
546-
sprintf(p, "%u", (unsigned)cv->i);
547-
#else
548545
sprintf(p, "%llu", (unsigned long long)cv->i);
549-
#endif
550546
break;
551547
case TOK_LCHAR:
552548
cstr_ccat(&cstr_buf, 'L');
@@ -1493,8 +1489,7 @@ static int expr_preprocess(TCCState *s1)
14931489
if (tok != ')')
14941490
expect("')'");
14951491
}
1496-
tok = TOK_CINT;
1497-
tokc.i = c;
1492+
goto c_number;
14981493
} else if (tok == TOK___HAS_INCLUDE ||
14991494
tok == TOK___HAS_INCLUDE_NEXT) {
15001495
t = tok;
@@ -1504,12 +1499,13 @@ static int expr_preprocess(TCCState *s1)
15041499
c = parse_include(s1, t - TOK___HAS_INCLUDE, 1);
15051500
if (tok != ')')
15061501
expect("')'");
1507-
tok = TOK_CINT;
1508-
tokc.i = c;
1502+
goto c_number;
15091503
} else {
15101504
/* if undefined macro, replace with zero */
1511-
tok = TOK_CINT;
1512-
tokc.i = 0;
1505+
c = 0;
1506+
c_number:
1507+
tok = TOK_CLLONG; /* type intmax_t */
1508+
tokc.i = c;
15131509
}
15141510
tok_str_add_tok(str);
15151511
}
@@ -2510,6 +2506,10 @@ static void parse_number(const char *p)
25102506
}
25112507
}
25122508

2509+
/* in #if/#elif expressions, all numbers have type (u)intmax_t anyway */
2510+
if (pp_expr)
2511+
lcount = 2;
2512+
25132513
/* Determine if it needs 64 bits and/or unsigned in order to fit */
25142514
if (ucount == 0 && b == 10) {
25152515
if (lcount <= (LONG_SIZE == 4)) {

tests/pp/21.c

+21
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,24 @@ NOT OK
3939
line __LINE__
4040
#define __LINE__ # ## #
4141
line __LINE__
42+
43+
----- 10 ------
44+
/* preprocessor numbers are (u)intmax_t */
45+
#if -2147483648 < 0
46+
1 true
47+
#endif
48+
#if -0x80000000 < 0
49+
2 true
50+
#endif
51+
#if -9223372036854775808U > 0
52+
3 true
53+
#endif
54+
#if -0x8000000000000000 > 0 // unsigned by overflow
55+
4 true
56+
#endif
57+
#if 1 << 31 > 2 && 1 << 32 > 2 && 1 << 63 < 2 && 1U << 63 > 2
58+
5 true
59+
#endif
60+
#if (1<<29) * 11 >= 1<<32 && defined DDD << 63 < 0
61+
6 true
62+
#endif

tests/pp/21.expect

+7
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,10 @@ OK
99
----- 5 ------
1010
line 39
1111
line ##
12+
----- 10 ------
13+
1 true
14+
2 true
15+
3 true
16+
4 true
17+
5 true
18+
6 true

0 commit comments

Comments
 (0)