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.
This commit is contained in:
grischka
2025-03-20 20:21:20 +01:00
parent f57cc34a0c
commit b3381269d7
3 changed files with 38 additions and 10 deletions

20
tccpp.c
View File

@@ -542,11 +542,7 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv)
case TOK_CLLONG:
case TOK_CULLONG:
/* XXX: not quite exact, but only useful for testing */
#ifdef _WIN32
sprintf(p, "%u", (unsigned)cv->i);
#else
sprintf(p, "%llu", (unsigned long long)cv->i);
#endif
break;
case TOK_LCHAR:
cstr_ccat(&cstr_buf, 'L');
@@ -1493,8 +1489,7 @@ static int expr_preprocess(TCCState *s1)
if (tok != ')')
expect("')'");
}
tok = TOK_CINT;
tokc.i = c;
goto c_number;
} else if (tok == TOK___HAS_INCLUDE ||
tok == TOK___HAS_INCLUDE_NEXT) {
t = tok;
@@ -1504,12 +1499,13 @@ static int expr_preprocess(TCCState *s1)
c = parse_include(s1, t - TOK___HAS_INCLUDE, 1);
if (tok != ')')
expect("')'");
tok = TOK_CINT;
tokc.i = c;
goto c_number;
} else {
/* if undefined macro, replace with zero */
tok = TOK_CINT;
tokc.i = 0;
c = 0;
c_number:
tok = TOK_CLLONG; /* type intmax_t */
tokc.i = c;
}
tok_str_add_tok(str);
}
@@ -2510,6 +2506,10 @@ static void parse_number(const char *p)
}
}
/* in #if/#elif expressions, all numbers have type (u)intmax_t anyway */
if (pp_expr)
lcount = 2;
/* Determine if it needs 64 bits and/or unsigned in order to fit */
if (ucount == 0 && b == 10) {
if (lcount <= (LONG_SIZE == 4)) {

View File

@@ -39,3 +39,24 @@ NOT OK
line __LINE__
#define __LINE__ # ## #
line __LINE__
----- 10 ------
/* preprocessor numbers are (u)intmax_t */
#if -2147483648 < 0
1 true
#endif
#if -0x80000000 < 0
2 true
#endif
#if -9223372036854775808U > 0
3 true
#endif
#if -0x8000000000000000 > 0 // unsigned by overflow
4 true
#endif
#if 1 << 31 > 2 && 1 << 32 > 2 && 1 << 63 < 2 && 1U << 63 > 2
5 true
#endif
#if (1<<29) * 11 >= 1<<32 && defined DDD << 63 < 0
6 true
#endif

View File

@@ -9,3 +9,10 @@ OK
----- 5 ------
line 39
line ##
----- 10 ------
1 true
2 true
3 true
4 true
5 true
6 true