Silence -Wpointer-to-int-cast warnings in newlib/libc/string/local.h.

Message ID 20260716233918.1010059-1-jdx@o2.pl
State New
Headers
Series Silence -Wpointer-to-int-cast warnings in newlib/libc/string/local.h. |

Commit Message

Jan Dubiec July 16, 2026, 11:38 p.m. UTC
  Compiling the library for a 16-bit target results in numerous warnings
(some of which are shown below) in the mem*, str*, and several other
functions. The existing code incorrectly assumes that pointers are 32
bits wide. This patch removes that assumption and fixes the resulting
warnings.

[...]
  CC       libc/string/libc_a-memchr.o
In file included from ../../../../../../../newlib/newlib/libc/string/memchr.c:35:
../../../../../../../newlib/newlib/libc/string/memchr.c: In function 'memchr':
../../../../../../../newlib/newlib/libc/string/local.h:24:25: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
   24 | #define UNALIGNED_X(X) ((long)(X) & (sizeof (long) - 1))
      |                         ^
../../../../../../../newlib/newlib/libc/string/memchr.c:50:10: note: in expansion of macro 'UNALIGNED_X'
   50 |   while (UNALIGNED_X(src))
      |          ^~~~~~~~~~~
  CC       libc/string/libc_a-memcmp.o
In file included from ../../../../../../../newlib/newlib/libc/string/memcmp.c:33:
../../../../../../../newlib/newlib/libc/string/memcmp.c: In function 'memcmp':
../../../../../../../newlib/newlib/libc/string/local.h:33:5: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
   33 |   (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
      |     ^
../../../../../../../newlib/newlib/libc/string/memcmp.c:63:38: note: in expansion of macro 'UNALIGNED_X_Y'
   63 |   if (!TOO_SMALL_LITTLE_BLOCK(n) && !UNALIGNED_X_Y(s1,s2))
      |                                      ^~~~~~~~~~~~~
../../../../../../../newlib/newlib/libc/string/local.h:33:39: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
   33 |   (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
      |                                       ^
../../../../../../../newlib/newlib/libc/string/memcmp.c:63:38: note: in expansion of macro 'UNALIGNED_X_Y'
   63 |   if (!TOO_SMALL_LITTLE_BLOCK(n) && !UNALIGNED_X_Y(s1,s2))
      |                                      ^~~~~~~~~~~~~
[...]

Signed-off-by: Jan Dubiec <jdx@o2.pl>
---
 newlib/libc/string/local.h | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)
  

Comments

Jeff Johnston July 21, 2026, 9:35 p.m. UTC | #1
Hi Jan,

The fallback for intptr_t is unnecessary.  According to
libc/include/sys/_intsup.h, gcc 3.2 or higher should support
the intptr info we need plus there is an #error statement if it isn't.  So,
the code should just use intptr_t.

-- Jeff J.

On Thu, Jul 16, 2026 at 7:40 PM Jan Dubiec <jdx@o2.pl> wrote:

> Compiling the library for a 16-bit target results in numerous warnings
> (some of which are shown below) in the mem*, str*, and several other
> functions. The existing code incorrectly assumes that pointers are 32
> bits wide. This patch removes that assumption and fixes the resulting
> warnings.
>
> [...]
>   CC       libc/string/libc_a-memchr.o
> In file included from
> ../../../../../../../newlib/newlib/libc/string/memchr.c:35:
> ../../../../../../../newlib/newlib/libc/string/memchr.c: In function
> 'memchr':
> ../../../../../../../newlib/newlib/libc/string/local.h:24:25: warning:
> cast from pointer to integer of different size [-Wpointer-to-int-cast]
>    24 | #define UNALIGNED_X(X) ((long)(X) & (sizeof (long) - 1))
>       |                         ^
> ../../../../../../../newlib/newlib/libc/string/memchr.c:50:10: note: in
> expansion of macro 'UNALIGNED_X'
>    50 |   while (UNALIGNED_X(src))
>       |          ^~~~~~~~~~~
>   CC       libc/string/libc_a-memcmp.o
> In file included from
> ../../../../../../../newlib/newlib/libc/string/memcmp.c:33:
> ../../../../../../../newlib/newlib/libc/string/memcmp.c: In function
> 'memcmp':
> ../../../../../../../newlib/newlib/libc/string/local.h:33:5: warning: cast
> from pointer to integer of different size [-Wpointer-to-int-cast]
>    33 |   (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) -
> 1)))
>       |     ^
> ../../../../../../../newlib/newlib/libc/string/memcmp.c:63:38: note: in
> expansion of macro 'UNALIGNED_X_Y'
>    63 |   if (!TOO_SMALL_LITTLE_BLOCK(n) && !UNALIGNED_X_Y(s1,s2))
>       |                                      ^~~~~~~~~~~~~
> ../../../../../../../newlib/newlib/libc/string/local.h:33:39: warning:
> cast from pointer to integer of different size [-Wpointer-to-int-cast]
>    33 |   (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) -
> 1)))
>       |                                       ^
> ../../../../../../../newlib/newlib/libc/string/memcmp.c:63:38: note: in
> expansion of macro 'UNALIGNED_X_Y'
>    63 |   if (!TOO_SMALL_LITTLE_BLOCK(n) && !UNALIGNED_X_Y(s1,s2))
>       |                                      ^~~~~~~~~~~~~
> [...]
>
> Signed-off-by: Jan Dubiec <jdx@o2.pl>
> ---
>  newlib/libc/string/local.h | 19 +++++++++++++++++--
>  1 file changed, 17 insertions(+), 2 deletions(-)
>
> diff --git a/newlib/libc/string/local.h b/newlib/libc/string/local.h
> index 012a30d16..79436ab69 100644
> --- a/newlib/libc/string/local.h
> +++ b/newlib/libc/string/local.h
> @@ -1,5 +1,6 @@
>  #include <_ansi.h>
>  #include <../ctype/local.h>
> +#include <stdint.h>
>
>  /* internal function to compute width of wide char. */
>  int __wcwidth (wint_t);
> @@ -17,11 +18,24 @@ int __wcwidth (wint_t);
>  # define __inhibit_loop_to_libcall
>  #endif
>
> +#ifdef __INTPTR_TYPE__
> +  #define INTPTRTYPE intptr_t
> +#else
> +  /* Fallback, just in case there is no intptr_t on a target... */
> +  #if __SIZEOF_POINTER__ > __SIZEOF_SHORT__
> +    /* 32-bit targets; the default */
> +       #define INTPTRTYPE long
> +  #else
> +    /* 16-bit targets; we silently assume sizeof(short)==2 and
> sizeof(long)==4 */
> +       #define INTPTRTYPE short
> +  #endif
> +#endif
> +
>  /* Nonzero if X is not aligned on a "long" boundary.
>   * This macro is used to skip a few bytes to find an aligned pointer.
>   * It's better to keep it as is even if _HAVE_HW_MISALIGNED_ACCESS is
> enabled,
>   * to avoid small performance penalties (if they are not zero).  */
> -#define UNALIGNED_X(X) ((long)(X) & (sizeof (long) - 1))
> +#define UNALIGNED_X(X) ((long)(INTPTRTYPE)(X) & (sizeof (long) - 1))
>
>  #ifdef _HAVE_HW_MISALIGNED_ACCESS
>  /* Hardware performs unaligned operations with little
> @@ -30,7 +44,8 @@ int __wcwidth (wint_t);
>  #else /* _HAVE_HW_MISALIGNED_ACCESS */
>  /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
>  #define UNALIGNED_X_Y(X, Y) \
> -  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
> +  (((long)(INTPTRTYPE)X & (sizeof (long) - 1)) | \
> +   ((long)(INTPTRTYPE)Y & (sizeof (long) - 1)))
>  #endif /* _HAVE_HW_MISALIGNED_ACCESS */
>
>  /* How many bytes are copied each iteration of the word copy loop.  */
> --
> 2.54.0
>
>
  

Patch

diff --git a/newlib/libc/string/local.h b/newlib/libc/string/local.h
index 012a30d16..79436ab69 100644
--- a/newlib/libc/string/local.h
+++ b/newlib/libc/string/local.h
@@ -1,5 +1,6 @@ 
 #include <_ansi.h>
 #include <../ctype/local.h>
+#include <stdint.h>
 
 /* internal function to compute width of wide char. */
 int __wcwidth (wint_t);
@@ -17,11 +18,24 @@  int __wcwidth (wint_t);
 # define __inhibit_loop_to_libcall
 #endif
 
+#ifdef __INTPTR_TYPE__
+  #define INTPTRTYPE intptr_t
+#else
+  /* Fallback, just in case there is no intptr_t on a target... */
+  #if __SIZEOF_POINTER__ > __SIZEOF_SHORT__
+    /* 32-bit targets; the default */
+	#define INTPTRTYPE long
+  #else
+    /* 16-bit targets; we silently assume sizeof(short)==2 and sizeof(long)==4 */
+	#define INTPTRTYPE short
+  #endif
+#endif
+
 /* Nonzero if X is not aligned on a "long" boundary.
  * This macro is used to skip a few bytes to find an aligned pointer.
  * It's better to keep it as is even if _HAVE_HW_MISALIGNED_ACCESS is enabled,
  * to avoid small performance penalties (if they are not zero).  */
-#define UNALIGNED_X(X) ((long)(X) & (sizeof (long) - 1))
+#define UNALIGNED_X(X) ((long)(INTPTRTYPE)(X) & (sizeof (long) - 1))
 
 #ifdef _HAVE_HW_MISALIGNED_ACCESS
 /* Hardware performs unaligned operations with little
@@ -30,7 +44,8 @@  int __wcwidth (wint_t);
 #else /* _HAVE_HW_MISALIGNED_ACCESS */
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED_X_Y(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((long)(INTPTRTYPE)X & (sizeof (long) - 1)) | \
+   ((long)(INTPTRTYPE)Y & (sizeof (long) - 1)))
 #endif /* _HAVE_HW_MISALIGNED_ACCESS */
 
 /* How many bytes are copied each iteration of the word copy loop.  */