Improve the warning about an integer constant overflow with the used overflown value and the potentially aimed value. This helps spotting the 0 to much in 0x80000000000000000.
Unified · Split
| @@ -1995,7 +1995,7 @@ ST_FUNC void preprocess(int is_bof) · 1994 unmodified lines | ||
| 1995 | 1995 | if (tok == '!' && is_bof) |
| 1996 | 1996 | /* '#!' is ignored at beginning to allow C scripts. */ |
| 1997 | 1997 | goto ignore; |
| 1998 | − tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc)); | |
| 1998 | + tcc_warning("ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc)); | |
| 1999 | 1999 | ignore: |
| 2000 | 2000 | skip_to_eol(0); |
| 2001 | 2001 | goto the_end; |
| @@ -2475,7 +2475,7 @@ static void parse_number(const char *p) · 473 unmodified lines | ||
| 2475 | 2475 | } |
| 2476 | 2476 | } |
| 2477 | 2477 | } else { |
| 2478 | − unsigned long long n, n1; | |
| 2478 | + unsigned long long n = 0, n1 = 0; | |
| 2479 | 2479 | int lcount, ucount, ov = 0; |
| 2480 | 2480 | const char *p1; |
| 2481 | 2481 | |
| @@ -2486,7 +2486,6 @@ static void parse_number(const char *p) · 4 unmodified lines | ||
| 2486 | 2486 | b = 8; |
| 2487 | 2487 | q++; |
| 2488 | 2488 | } |
| 2489 | − n = 0; | |
| 2490 | 2489 | while(1) { |
| 2491 | 2490 | t = *q++; |
| 2492 | 2491 | /* no need for checks except for base 10 / 8 errors */ |
| @@ -2500,11 +2499,13 @@ static void parse_number(const char *p) · 7 unmodified lines | ||
| 2500 | 2499 | t = t - '0'; |
| 2501 | 2500 | if (t >= b) |
| 2502 | 2501 | tcc_error("invalid digit"); |
| 2503 | − n1 = n; | |
| 2504 | 2502 | n = n * b + t; |
| 2505 | − /* detect overflow */ | |
| 2506 | − if (n1 >= 0x1000000000000000ULL && n / b != n1) | |
| 2507 | − ov = 1; | |
| 2503 | + if (!ov) | |
| 2504 | + /* detect overflow */ | |
| 2505 | + if (n1 >= 0x1000000000000000ULL && n / b != n1) | |
| 2506 | + ov = 1; | |
| 2507 | + else | |
| 2508 | + n1 = n; | |
| 2508 | 2509 | } |
| 2509 | 2510 | |
| 2510 | 2511 | /* Determine the characteristics (unsigned and/or 64bit) the type of |
| @@ -2554,7 +2555,26 @@ static void parse_number(const char *p) · 43 unmodified lines | ||
| 2554 | 2555 | } |
| 2555 | 2556 | |
| 2556 | 2557 | if (ov) |
| 2557 | − tcc_warning("integer constant overflow"); | |
| 2558 | + /* Give a warning with values in case of an overflow. This helps to | |
| 2559 | + spot the 0 too much in 0x8000'0000'0000'0000'0. It may even be | |
| 2560 | + better to use a 0x8000'0000'0000'0000 from n1 instead of a 0 from | |
| 2561 | + n after the overflow. This is at least undefined behavior. | |
| 2562 | + The C99 to C23 standards state: | |
| 2563 | + "Each constant shall have a type and the value of a constant | |
| 2564 | + shall be in the range of representable values for its type." | |
| 2565 | + "If an integer constant cannot be represented by any type ..., | |
| 2566 | + then the integer constant has no type." | |
| 2567 | + The C++ standards state: | |
| 2568 | + "A program is ill-formed if one of its translation units contains | |
| 2569 | + an integer-literal that cannot be represented by any of the | |
| 2570 | + allowed types." */ | |
| 2571 | + tcc_warning( | |
| 2572 | + b == 8 | |
| 2573 | + ? "integer constant overflow, using %#llo; did you mean %#llo?" | |
| 2574 | + : b == 10 | |
| 2575 | + ? "integer constant overflow, using %llu, did you mean %llu?" | |
| 2576 | + : "integer constant overflow, using %#llx; did you mean %#llx?", | |
| 2577 | + n, n1); | |
| 2558 | 2578 | |
| 2559 | 2579 | tok = TOK_CINT; |
| 2560 | 2580 | if (lcount) { |