diff --git a/src/string/strlen.c b/src/string/strlen.c index 929ddcb..bb67699 100644 --- a/src/string/strlen.c +++ b/src/string/strlen.c @@ -10,9 +10,18 @@ size_t strlen(const char *s) { const char *a = s; - const size_t *w; +#ifdef __GNUC__ + typedef size_t __attribute__((__may_alias__)) word; + + const word *w; for (; (uintptr_t)s % ALIGN; s++) if (!*s) return s-a; + /* The last access of this loop may be OOB, but falls inside + the same page as a byte of any valid string passed to strlen. */ for (w = (const void *)s; !HASZERO(*w); w++); for (s = (const void *)w; *s; s++); +#else + /* Pure C fallback with no OOB access or aliasing violations. */ + for (; *s; s++); +#endif return s-a; }