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
