Files
vlibc/src/string/memcpy.c
T
huntedbytheirsandSisyphus 6854c7771d style(string): satisfy clang-tidy and clang-format for final-wave gate
Suppress clang-analyzer-security buffer-handling diagnostics on the
plan-mandated __builtin_memcpy word loads and bugprone swappable-
parameter diagnostics on the C-standard signatures; wrap the autoconf
substitution tokens in clang-format off/on (the space clang-format wants
before the closing @ would break config.status substitution).

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <[email protected]>
2026-08-31 21:34:25 -04:00

53 lines
1.5 KiB
C

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
/*
* Copy n bytes from src to dst. The regions must not overlap (restrict).
* Word-at-a-time: copy whole unsigned long words once dst is aligned, with
* a byte head and tail. Word loads and stores go through __builtin_memcpy
* so unaligned src is handled without undefined behavior.
*
* The word-copy loop below is the canonical memcpy idiom; GCC's
* -ftree-loop-distribute-patterns (on by default at -O2 and -O3) rewrites
* it into a call to memcpy() — this very function — causing infinite
* self-recursion and stack overflow. Disable that one transformation for
* this function only.
*/
__attribute__((optimize("no-tree-loop-distribute-patterns"))) void *
memcpy(void *restrict dst, const void *restrict src, size_t n) // NOLINT(bugprone-*)
{
const unsigned long word = sizeof(unsigned long);
unsigned char *d = dst;
const unsigned char *s = src;
/* Copy the unaligned head byte-wise. */
for (; (unsigned long)d % word != 0 && n != 0; n--)
{
*d++ = *s++;
}
/* Copy whole words. */
while (n >= word)
{
unsigned long w;
__builtin_memcpy(&w, s, sizeof w); // NOLINT(clang-analyzer-security.insecureAPI.*)
__builtin_memcpy(d, &w, sizeof w); // NOLINT(clang-analyzer-security.insecureAPI.*)
d += word;
s += word;
n -= word;
}
/* Copy the remaining tail byte-wise. */
while (n != 0)
{
*d++ = *s++;
n--;
}
return dst;
}