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

Re: [PATCH] fast-export: avoid NULL pointer arithmetic

From
René Scharfe <l.s.r@web.de>
Date
May 10, 2018, 09:24 UTC
Message-ID
<99d443cd-e817-7db5-f758-bf4cf47f7c06@web.de>
In-Reply-To
<d50a4d5d-3b99-453e-1b52-4e733453fb78@web.de>
Am 09.05.2018 um 23:06 schrieb René Scharfe:
Show 12 quoted lines
> Clang 6 reports the following warning, which is turned into an error in a
> DEVELOPER build:
> 
> 	builtin/fast-export.c:162:28: error: performing pointer arithmetic on a null pointer has undefined behavior [-Werror,-Wnull-pointer-arithmetic]
> 		return ((uint32_t *)NULL) + mark;
> 		       ~~~~~~~~~~~~~~~~~~ ^
> 	1 error generated.
> 
> The compiler is correct, and the error message speaks for itself.  There
> is no need for any undefined operation -- just cast mark to void * or
> uint32_t after an intermediate cast to uintptr_t.  That encodes the
> integer value into a pointer and later decodes it as intended.

Having thought about it a bit more I have to say: That seems to work, but it's not portable.

The standard says about uintptr_t that "any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer". So void * -> uintptr_t -> void * is a proper roundtrip, but that doesn't imply that casting arbitrary uintptr_t values to void * would be lossless.

I don't know an architecture where this would bite us, but I wonder if there is a cleaner way. Perhaps changing the type of the decoration member of struct decoration_entry in decorate.h to uintptr_t?

Show 33 quoted lines
> While at it remove an outdated comment -- intptr_t has been used since
> ffe659f94d (parse-options: make some arguments optional, add callbacks),
> committed in October 2007.
> 
> Signed-off-by: Rene Scharfe <l.s.r@web.de>
> ---
>   builtin/fast-export.c | 7 +++----
>   1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/builtin/fast-export.c b/builtin/fast-export.c
> index 530df12f05..fa556a3c93 100644
> --- a/builtin/fast-export.c
> +++ b/builtin/fast-export.c
> @@ -156,15 +156,14 @@ static void anonymize_path(struct strbuf *out, const char *path,
>   	}
>   }
>   
> -/* Since intptr_t is C99, we do not use it here */
> -static inline uint32_t *mark_to_ptr(uint32_t mark)
> +static inline void *mark_to_ptr(uint32_t mark)
>   {
> -	return ((uint32_t *)NULL) + mark;
> +	return (void *)(uintptr_t)mark;
>   }
>   
>   static inline uint32_t ptr_to_mark(void * mark)
>   {
> -	return (uint32_t *)mark - (uint32_t *)NULL;
> +	return (uint32_t)(uintptr_t)mark;
>   }
>   
>   static inline void mark_object(struct object *object, uint32_t mark)
> 
Previous: Johannes SchindelinNext: Junio C Hamano
Message 3 of 16 in “fast-export: avoid NULL pointer arithmetic”
  1. fast-export: avoid NULL pointer arithmeticRené Scharfe, May 9, 2018
  2. Johannes SchindelinMay 9, 2018
  3. René ScharfeMay 10, 2018
  4. Junio C HamanoMay 10, 2018
  5. René ScharfeMay 10, 2018
  6. Junio C HamanoMay 11, 2018
  7. Junio C HamanoMay 11, 2018
  8. Duy NguyenMay 11, 2018
  9. Jeff KingMay 11, 2018
  10. Duy NguyenMay 11, 2018
  11. Duy NguyenMay 11, 2018
  12. Jeff KingMay 11, 2018
  13. René ScharfeMay 12, 2018
  14. René ScharfeMay 12, 2018
  15. Junio C HamanoMay 14, 2018
  16. René ScharfeMay 15, 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.