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

Re: [PATCH 2/2] read-cache: fix an -Wmaybe-uninitialized warning

From
Jeff King <peff@peff.net>
Date
Mar 20, 2018, 04:36 UTC
Message-ID
<20180320043652.GC13302@sigill.intra.peff.net>
In-Reply-To
<6d434e76-cfa0-2a6e-f163-b54316a24cee@ramsayjones.plus.com>
On Mon, Mar 19, 2018 at 05:56:11PM +0000, Ramsay Jones wrote:
Show 28 quoted lines
> For the purposes of this discussion, the ce_write_entry() function has
> three code blocks of interest, that look like so:
> 
>         /* block #1 */
>         if (ce->ce_flags & CE_STRIP_NAME) {
>                 saved_namelen = ce_namelen(ce);
>                 ce->ce_namelen = 0;
>         }
> 
>         /* block #2 */
>         /*
> 	 * several code blocks that contain, among others, calls
>          * to copy_cache_entry_to_ondisk(ondisk, ce);
>          */
> 
>         /* block #3 */
>         if (ce->ce_flags & CE_STRIP_NAME) {
>                 ce->ce_namelen = saved_namelen;
>                 ce->ce_flags &= ~CE_STRIP_NAME;
>         }
> 
> The warning implies that gcc thinks it is possible that the first
> block is not entered, the calls to copy_cache_entry_to_ondisk()
> could toggle the CE_STRIP_NAME flag on, thereby entering block #3
> with saved_namelen unset. However, the copy_cache_entry_to_ondisk()
> function does not write to ce->ce_flags (it only reads). gcc could
> easily determine this, since that function is local to this file,
> but it obviously doesn't.

Weird. It seems like it would be pretty easy for it to know that we don't write the flags field at all. But I also don't see any other thing that would fool the compiler.

Show 5 quoted lines
> In order to suppress this warning, we make it clear to the reader
> (human and compiler), that block #3 will only be entered when the
> first block has been entered, by introducing a new 'stripped_name'
> boolean variable. We also take the opportunity to change the type
> of 'saved_namelen' to 'unsigned int' to match ce->ce_namelen.

These probably both ought to be size_t, but it makes sense to match ce_namelen for now.

Show 12 quoted lines
> diff --git a/read-cache.c b/read-cache.c
> index 2eb81a66b..49607ddcd 100644
> --- a/read-cache.c
> +++ b/read-cache.c
> @@ -2104,13 +2104,15 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce,
>  			  struct strbuf *previous_name, struct ondisk_cache_entry *ondisk)
>  {
>  	int size;
> -	int saved_namelen = saved_namelen; /* compiler workaround */
>  	int result;
> +	unsigned int saved_namelen;
> +	int stripped_name = 0;
Maybe too clever, but I think you could just do:
  unsigned int saved_namelen = 0;
  ...
	saved_namelen = ce_namelen(ce);
  ...
  if (saved_namelen)
	ce->ce_namelen = saved_namelen;
  ce->ce_flags &= ~CE_STRIP_NAME;

the zero-length name case (if that's even legal) would work out the same.

That probably falls under the category of bikeshedding, though.
-Peff
Previous: Ramsay JonesNext: Ramsay Jones
Message 2 of 4 in “read-cache: fix an -Wmaybe-uninitialized warning”
  1. 2/2 read-cache: fix an -Wmaybe-uninitialized warningRamsay Jones, Mar 19, 2018
  2. Jeff KingMar 20, 2018
  3. Ramsay JonesMar 20, 2018
  4. Jeff KingMar 21, 2018

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.