git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 06/10] global: fix unsigned integer promotions in ternary statements

From
Jeff King <peff@peff.net>
Date
Dec 1, 2024, 21:59 UTC
Message-ID
<20241201215911.GD145938@coredump.intra.peff.net>
In-Reply-To
<20241129-pks-sign-compare-v1-6-fc406b984bc9@pks.im>
On Fri, Nov 29, 2024 at 02:13:27PM +0100, Patrick Steinhardt wrote:
Show 11 quoted lines
> diff --git a/builtin/blame.c b/builtin/blame.c
> index f0d209791e44025b1965cd447cf4fc1e2ca5f009..6c6b0c7ef1a4d992064c7664bbf1229ef0286b97 100644
> --- a/builtin/blame.c
> +++ b/builtin/blame.c
> @@ -470,7 +470,8 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int
>  
>  	for (cnt = 0; cnt < ent->num_lines; cnt++) {
>  		char ch;
> -		int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? the_hash_algo->hexsz : abbrev;
> +		int length = (opt & OUTPUT_LONG_OBJECT_NAME) ?
> +			cast_size_t_to_int(the_hash_algo->hexsz) : abbrev;

Hmm. I'm surprised that -Wsign-compare would trigger here. We are not comparing, but assigning. I'd have thought the actual error is the truncation from the size_t the_hash_algo->hexsz down to "length".

But the actual error from gcc is:
  builtin/blame.c:472:87: error: operand of ‘?:’ changes signedness from ‘int’ to ‘size_t’ {aka ‘long unsigned int’} due to unsignedness of other operand [-Werror=sign-compare]
    472 |                 int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? the_hash_algo->hexsz : abbrev;
        |                                                                                       ^~~~~~

So that makes sense that "abbrev" is promoted to unsigned to match the other side, though I still think it's a little weird this comes via -Wsign-compare.

Another solution would be to change "abbrev" into a size_t. But then we'd still have truncation assigning to "length", unless we also make that a size_t. But wouldn't that be the more natural type? We pass it to memset() later.

We also subtract from it (without checking that it doesn't become negative!), and use it with a printf("%.*s"). The latter does want an int because of the lousy historical interface. IMHO we are probably better off using fwrite() or strbuf_add() instead of "%.*s" specifiers. In this case, I think it's just:

  fwrite(hex, 1, length, stdout);

(that assumes "length" is clamped to the hex size; I think it is here but I also would not be opposed to a helper function that checks it against the string length).

So I don't think what you've written above is _wrong_. But I think that ultimately the right type here probably is size_t, and I worry that sprinkling casts around makes it harder to see that. It converts what would be a compile-time complaint (the truncation and sign conversion) into a run-time one (that in this case I suspect can't be triggered, but as a general rule may be something that _can_ be a problem but which our tests are unlikely to actually poke at). I dunno.

I didn't dig carefully into the other ones, but I suspect they may be similar. E.g.:

Show 13 quoted lines
> diff --git a/builtin/patch-id.c b/builtin/patch-id.c
> index 56585757477911c96bbb9ef2cf3710691b8e744e..87fa586c4d552ba61cd2ac2cf079d68241eb3275 100644
> --- a/builtin/patch-id.c
> +++ b/builtin/patch-id.c
> @@ -163,7 +163,7 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
>  			after--;
>  
>  		/* Add line to hash algo (possibly removing whitespace) */
> -		len = verbatim ? strlen(line) : remove_space(line);
> +		len = verbatim ? cast_size_t_to_int(strlen(line)) : remove_space(line);
>  		patchlen += len;
>  		the_hash_algo->update_fn(&ctx, line, len);
>  	}

Here we are assigning the result of strlen() to an int, but I think it's unbounded (it points to a strbuf we read from stdin). The cast helper does at least mean we'll bail rather than continue on bogus input, but consistently using size_t seems better still to me.

-Peff
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 9 of 66 in “Start compiling with `-Wsign-compare`”
  1. 00/10 Start compiling with `-Wsign-compare`Patrick Steinhardt, Nov 29, 2024
  2. 02/10 compat/regex: explicitly ignore "-Wsign-compare" warningsPatrick Steinhardt, Nov 29, 2024
  3. 01/10 git-compat-util: introduce macros to disable "-Wsign-compare" warningsPatrick Steinhardt, Nov 29, 2024
  4. 03/10 compat/win32: fix -Wsign-compare warning in "wWinMain()"Patrick Steinhardt, Nov 29, 2024
  5. 05/10 config.mak.dev: drop `-Wno-sign-compare`Patrick Steinhardt, Nov 29, 2024
  6. 06/10 global: fix unsigned integer promotions in ternary statementsPatrick Steinhardt, Nov 29, 2024
  7. shejialuoNov 30, 2024
  8. Patrick SteinhardtDec 2, 2024
  9. Jeff KingDec 1, 2024
  10. Patrick SteinhardtDec 2, 2024
  11. 04/10 global: mark code units that generate warnings with `-Wsign-compare`Patrick Steinhardt, Nov 29, 2024
  12. 07/10 diff.h: fix index used to loop through unsigned integerPatrick Steinhardt, Nov 29, 2024
  13. 09/10 daemon: fix loops that have mismatching integer typesPatrick Steinhardt, Nov 29, 2024
  14. Jeff KingDec 1, 2024
  15. Patrick SteinhardtDec 2, 2024
  16. Jeff KingDec 5, 2024
  17. 08/10 global: trivial conversions to fix `-Wsign-compare` warningsPatrick Steinhardt, Nov 29, 2024
  18. Jeff KingDec 1, 2024
  19. Patrick SteinhardtDec 2, 2024
  20. 10/10 daemon: fix type of `max_connections`Patrick Steinhardt, Nov 29, 2024
  21. Jeff KingDec 1, 2024
  22. shejialuoNov 30, 2024
  23. Patrick SteinhardtDec 2, 2024
  24. Jeff KingDec 1, 2024
  25. Patrick SteinhardtDec 2, 2024
  26. 00/15 Start compiling with `-Wsign-compare`Patrick Steinhardt, Dec 5, 2024
  27. 01/15 git-compat-util: introduce macros to disable "-Wsign-compare" warningsPatrick Steinhardt, Dec 5, 2024
  28. 02/15 compat/regex: explicitly ignore "-Wsign-compare" warningsPatrick Steinhardt, Dec 5, 2024
  29. 03/15 compat/win32: fix -Wsign-compare warning in "wWinMain()"Patrick Steinhardt, Dec 5, 2024
  30. 05/15 config.mak.dev: drop `-Wno-sign-compare`Patrick Steinhardt, Dec 5, 2024
  31. 04/15 global: mark code units that generate warnings with `-Wsign-compare`Patrick Steinhardt, Dec 5, 2024
  32. 06/15 diff.h: fix index used to loop through unsigned integerPatrick Steinhardt, Dec 5, 2024
  33. 07/15 sign-compare: 32-bit supportPatrick Steinhardt, Dec 5, 2024
  34. Jeff KingDec 5, 2024
  35. Patrick SteinhardtDec 6, 2024
  36. 08/15 global: trivial conversions to fix `-Wsign-compare` warningsPatrick Steinhardt, Dec 5, 2024
  37. 09/15 daemon: fix loops that have mismatching integer typesPatrick Steinhardt, Dec 5, 2024
  38. 11/15 gpg-interface: address -Wsign-comparison warningsPatrick Steinhardt, Dec 5, 2024
  39. 10/15 daemon: fix type of `max_connections`Patrick Steinhardt, Dec 5, 2024
  40. 12/15 builtin/blame: fix type of `length` variable when emitting object IDPatrick Steinhardt, Dec 5, 2024
  41. 13/15 builtin/patch-id: fix type of `get_one_patchid()`Patrick Steinhardt, Dec 5, 2024
  42. 14/15 scalar: address -Wsign-compare warningsPatrick Steinhardt, Dec 5, 2024
  43. 15/15 t/helper: don't depend on implicit wraparoundPatrick Steinhardt, Dec 5, 2024
  44. 00/16 Start compiling with `-Wsign-compare`Patrick Steinhardt, Dec 6, 2024
  45. 01/16 git-compat-util: introduce macros to disable "-Wsign-compare" warningsPatrick Steinhardt, Dec 6, 2024
  46. karthik nayakDec 6, 2024
  47. 02/16 compat/regex: explicitly ignore "-Wsign-compare" warningsPatrick Steinhardt, Dec 6, 2024
  48. 03/16 compat/win32: fix -Wsign-compare warning in "wWinMain()"Patrick Steinhardt, Dec 6, 2024
  49. 05/16 config.mak.dev: drop `-Wno-sign-compare`Patrick Steinhardt, Dec 6, 2024
  50. 04/16 global: mark code units that generate warnings with `-Wsign-compare`Patrick Steinhardt, Dec 6, 2024
  51. 06/16 diff.h: fix index used to loop through unsigned integerPatrick Steinhardt, Dec 6, 2024
  52. 07/16 csum-file: fix -Wsign-compare warning on 32-bit platformPatrick Steinhardt, Dec 6, 2024
  53. 08/16 pkt-line: fix -Wsign-compare warning on 32 bit platformPatrick Steinhardt, Dec 6, 2024
  54. Jeff KingDec 8, 2024
  55. Junio C HamanoDec 9, 2024
  56. 09/16 global: trivial conversions to fix `-Wsign-compare` warningsPatrick Steinhardt, Dec 6, 2024
  57. 10/16 daemon: fix loops that have mismatching integer typesPatrick Steinhardt, Dec 6, 2024
  58. 11/16 daemon: fix type of `max_connections`Patrick Steinhardt, Dec 6, 2024
  59. 12/16 gpg-interface: address -Wsign-comparison warningsPatrick Steinhardt, Dec 6, 2024
  60. 13/16 builtin/blame: fix type of `length` variable when emitting object IDPatrick Steinhardt, Dec 6, 2024
  61. Johannes SchindelinJan 8, 2025
  62. Patrick SteinhardtJan 9, 2025
  63. 14/16 builtin/patch-id: fix type of `get_one_patchid()`Patrick Steinhardt, Dec 6, 2024
  64. 15/16 scalar: address -Wsign-compare warningsPatrick Steinhardt, Dec 6, 2024
  65. 16/16 t/helper: don't depend on implicit wraparoundPatrick Steinhardt, Dec 6, 2024
  66. karthik nayakDec 6, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.