From b3381269d78b201bb9b9b427f830cde357de6d45 Mon Sep 17 00:00:00 2001 From: grischka Date: Thu, 20 Mar 2025 20:21:20 +0100 Subject: [PATCH] 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. --- tccpp.c | 20 ++++++++++---------- tests/pp/21.c | 21 +++++++++++++++++++++ tests/pp/21.expect | 7 +++++++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/tccpp.c b/tccpp.c index 8d75e972..f2d534cd 100644 --- a/tccpp.c +++ b/tccpp.c @@ -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)) { diff --git a/tests/pp/21.c b/tests/pp/21.c index c28988d4..2f447c1c 100644 --- a/tests/pp/21.c +++ b/tests/pp/21.c @@ -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 diff --git a/tests/pp/21.expect b/tests/pp/21.expect index 297b4d4c..eafaeed8 100644 --- a/tests/pp/21.expect +++ b/tests/pp/21.expect @@ -9,3 +9,10 @@ OK ----- 5 ------ line 39 line ## +----- 10 ------ +1 true +2 true +3 true +4 true +5 true +6 true