Hi,

Can you point to where in the C standard this is treated as undefined behavior?

Best regards,
Kjetil Oftedal

On Tue, 7 Jan 2025 at 13:10, Marcus Haehnel
<[email protected]> wrote:
>
> From: Frank Mehnert <[email protected]>
>
> It is undefined behavior to compare two pointers belonging to different
> objects. This includes the case where the addition overflows. Clang-20
> seems to follow this rule more eagerly and optimizes away the old test.
>
> Fix the test by performing the addition on uintptr_t values rather than
> on on char pointers.
>
> See also https://github.com/llvm/llvm-project/issues/121909.
>
> Signed-off-by: Marcus Haehnel <[email protected]>
> ---
>  libc/string/generic/strnlen.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/libc/string/generic/strnlen.c b/libc/string/generic/strnlen.c
> index 4d4cde84f..82d4122ec 100644
> --- a/libc/string/generic/strnlen.c
> +++ b/libc/string/generic/strnlen.c
> @@ -29,15 +29,17 @@
>     '\0' terminator is found in that many characters, return MAXLEN.  */
>  size_t strnlen (const char *str, size_t maxlen)
>  {
> -  const char *char_ptr, *end_ptr = str + maxlen;
> +  const char *char_ptr, *end_ptr;
>    const unsigned long int *longword_ptr;
>    unsigned long int longword, himagic, lomagic;
>
>    if (maxlen == 0)
>      return 0;
>
> -  if (__builtin_expect (end_ptr < str, 0))
> +  if (__builtin_expect ((uintptr_t)str + maxlen < (uintptr_t)str, 0))
>      end_ptr = (const char *) ~0UL;
> +  else
> +    end_ptr = str + maxlen;
>
>    /* Handle the first few characters by reading one character at a time.
>       Do this until CHAR_PTR is aligned on a longword boundary.  */
> --
> 2.47.1
>
> _______________________________________________
> devel mailing list -- [email protected]
> To unsubscribe send an email to [email protected]
_______________________________________________
devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to