It's undefined behavior.

* lib/memchr.c (__memchr): Add _GL_ATTRIBUTE_MAY_ALIAS to
the longword typedef.
* lib/memchr2.c (memchr2): Likewise.
* lib/memrchr.c (__memrchr): Likewise.
* lib/rawmemchr.c (rawmemchr): Likewise.
* lib/strchrnul.c (strchrnul): Likewise.
---
 ChangeLog       | 11 +++++++++++
 lib/memchr.c    |  2 +-
 lib/memchr2.c   |  2 +-
 lib/memrchr.c   |  2 +-
 lib/rawmemchr.c |  2 +-
 lib/strchrnul.c |  2 +-
 6 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7a5d11b2c9..a941f89cec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2026-07-26  Lasse Collin  <[email protected]>
+
+       Fix strict aliasing violations in a few string functions
+       (undefined behavior).
+       * lib/memchr.c (__memchr): Add _GL_ATTRIBUTE_MAY_ALIAS to
+       the longword typedef.
+       * lib/memchr2.c (memchr2): Likewise.
+       * lib/memrchr.c (__memrchr): Likewise.
+       * lib/rawmemchr.c (rawmemchr): Likewise.
+       * lib/strchrnul.c (strchrnul): Likewise.
+
 2026-07-25  Bruno Haible  <[email protected]>
 
        tests: Avoid some runtime errors with Fil-C.
diff --git a/lib/memchr.c b/lib/memchr.c
index 6adac7e179..0e3c2c8a35 100644
--- a/lib/memchr.c
+++ b/lib/memchr.c
@@ -63,7 +63,7 @@ __memchr (void const *s, int c_in, size_t n)
      performance.  On 64-bit hardware, unsigned long is generally 64
      bits already.  Change this typedef to experiment with
      performance.  */
-  typedef unsigned long int longword;
+  typedef unsigned long int longword _GL_ATTRIBUTE_MAY_ALIAS;
 
   unsigned reg_char c = (unsigned char) c_in;
 
diff --git a/lib/memchr2.c b/lib/memchr2.c
index 128144d7f3..610f9165a0 100644
--- a/lib/memchr2.c
+++ b/lib/memchr2.c
@@ -40,7 +40,7 @@ memchr2 (void const *s, int c1_in, int c2_in, size_t n)
      performance.  On 64-bit hardware, unsigned long is generally 64
      bits already.  Change this typedef to experiment with
      performance.  */
-  typedef unsigned long int longword;
+  typedef unsigned long int longword _GL_ATTRIBUTE_MAY_ALIAS;
 
   unsigned char c1 = (unsigned char) c1_in;
   unsigned char c2 = (unsigned char) c2_in;
diff --git a/lib/memrchr.c b/lib/memrchr.c
index a7683c9aea..b859288d68 100644
--- a/lib/memrchr.c
+++ b/lib/memrchr.c
@@ -50,7 +50,7 @@ __memrchr (void const *s, int c_in, size_t n)
      performance.  On 64-bit hardware, unsigned long is generally 64
      bits already.  Change this typedef to experiment with
      performance.  */
-  typedef unsigned long int longword;
+  typedef unsigned long int longword _GL_ATTRIBUTE_MAY_ALIAS;
 
   unsigned reg_char c = (unsigned char) c_in;
 
diff --git a/lib/rawmemchr.c b/lib/rawmemchr.c
index 9714698fcc..4eaada4774 100644
--- a/lib/rawmemchr.c
+++ b/lib/rawmemchr.c
@@ -42,7 +42,7 @@ rawmemchr (const void *s, int c_in)
 # else
 
   /* You can change this typedef to experiment with performance.  */
-  typedef uintptr_t longword;
+  typedef uintptr_t longword _GL_ATTRIBUTE_MAY_ALIAS;
   /* Verify that the longword type lacks padding bits.  */
   static_assert (UINTPTR_WIDTH == UCHAR_WIDTH * sizeof (uintptr_t));
 
diff --git a/lib/strchrnul.c b/lib/strchrnul.c
index c3bfebce28..2e813bf580 100644
--- a/lib/strchrnul.c
+++ b/lib/strchrnul.c
@@ -28,7 +28,7 @@ strchrnul (const char *s, int c_in)
      performance.  On 64-bit hardware, unsigned long is generally 64
      bits already.  Change this typedef to experiment with
      performance.  */
-  typedef unsigned long int longword;
+  typedef unsigned long int longword _GL_ATTRIBUTE_MAY_ALIAS;
 
   unsigned char c = (unsigned char) c_in;
   if (!c)
-- 
2.55.0


Reply via email to