1 #include "libc.h"
2 #include <limits.h>
3 #include <stdint.h>
4 #include <string.h>
5 
6 #define ALIGN (sizeof(size_t))
7 #define ONES ((size_t)-1 / UCHAR_MAX)
8 #define HIGHS (ONES * (UCHAR_MAX / 2 + 1))
9 #define HASZERO(x) (((x)-ONES) & ~(x)&HIGHS)
10 
__stpcpy(char * restrict d,const char * restrict s)11 char* __stpcpy(char* restrict d, const char* restrict s) {
12 #if !__has_feature(address_sanitizer)
13     // This reads past the end of the string, which is usually OK since
14     // it won't cross a page boundary.  But under ASan, even one byte
15     // past the actual end is diagnosed.
16     if ((uintptr_t)s % ALIGN == (uintptr_t)d % ALIGN) {
17         for (; (uintptr_t)s % ALIGN; s++, d++)
18             if (!(*d = *s))
19                 return d;
20         size_t* wd = (void*)d;
21         const size_t* ws = (const void*)s;
22         for (; !HASZERO(*ws); *wd++ = *ws++)
23             ;
24         d = (void*)wd;
25         s = (const void*)ws;
26     }
27 #endif
28     for (; (*d = *s); s++, d++)
29         ;
30 
31     return d;
32 }
33 
34 weak_alias(__stpcpy, stpcpy);
35