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 | if (tok == '!' && is_bof) | 1995 | if (tok == '!' && is_bof) |
| 1996 | /* '#!' is ignored at beginning to allow C scripts. */ | 1996 | /* '#!' is ignored at beginning to allow C scripts. */ |
| 1997 | goto ignore; | 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 | ignore: | 1999 | ignore: |
| 2000 | skip_to_eol(0); | 2000 | skip_to_eol(0); |
| 2001 | goto the_end; | 2001 | goto the_end; |
| @@ -2475,7 +2475,7 @@ static void parse_number(const char *p) · 473 unmodified lines | |||
| 2475 | } | 2475 | } |
| 2476 | } | 2476 | } |
| 2477 | } else { | 2477 | } else { |
| 2478 | unsigned long long n, n1; | 2478 | unsigned long long n = 0, n1 = 0; |
| 2479 | int lcount, ucount, ov = 0; | 2479 | int lcount, ucount, ov = 0; |
| 2480 | const char *p1; | 2480 | const char *p1; |
| 2481 | 2481 | ||
| @@ -2486,7 +2486,6 @@ static void parse_number(const char *p) · 4 unmodified lines | |||
| 2486 | b = 8; | 2486 | b = 8; |
| 2487 | q++; | 2487 | q++; |
| 2488 | } | 2488 | } |
| 2489 | n = 0; | ||
| 2490 | while(1) { | 2489 | while(1) { |
| 2491 | t = *q++; | 2490 | t = *q++; |
| 2492 | /* no need for checks except for base 10 / 8 errors */ | 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 | t = t - '0'; | 2499 | t = t - '0'; |
| 2501 | if (t >= b) | 2500 | if (t >= b) |
| 2502 | tcc_error("invalid digit"); | 2501 | tcc_error("invalid digit"); |
| 2503 | n1 = n; | ||
| 2504 | n = n * b + t; | 2502 | n = n * b + t; |
| 2505 | /* detect overflow */ | 2503 | if (!ov) |
| 2506 | if (n1 >= 0x1000000000000000ULL && n / b != n1) | 2504 | /* detect overflow */ |
| 2507 | ov = 1; | 2505 | if (n1 >= 0x1000000000000000ULL && n / b != n1) |
| 2506 | ov = 1; | ||
| 2507 | else | ||
| 2508 | n1 = n; | ||
| 2508 | } | 2509 | } |
| 2509 | 2510 | ||
| 2510 | /* Determine the characteristics (unsigned and/or 64bit) the type of | 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 | if (ov) | 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 | tok = TOK_CINT; | 2579 | tok = TOK_CINT; |
| 2560 | if (lcount) { | 2580 | if (lcount) { |