diff --git a/compiler-rt/lib/hwasan/hwasan_memintrinsics.cpp b/compiler-rt/lib/hwasan/hwasan_memintrinsics.cpp index fab017aae60bed..ea7f5ce40b0744 100644 --- a/compiler-rt/lib/hwasan/hwasan_memintrinsics.cpp +++ b/compiler-rt/lib/hwasan/hwasan_memintrinsics.cpp @@ -40,5 +40,5 @@ void *__hwasan_memmove(void *to, const void *from, uptr size) { reinterpret_cast(to), size); CheckAddressSized( reinterpret_cast(from), size); - return memmove(UntagPtr(to), UntagPtr(from), size); + return memmove(to, from, size); } diff --git a/compiler-rt/test/hwasan/TestCases/custom-memmove.c b/compiler-rt/test/hwasan/TestCases/custom-memmove.c new file mode 100644 index 00000000000000..7b15e06234debd --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/custom-memmove.c @@ -0,0 +1,39 @@ +// Test that custom memmove implementations instrumented by HWASan do not cause +// false positives. + +// RUN: %clang_hwasan %s -o %t +// RUN: %run %t + +#include +#include +#include + +void *memmove(void *Dest, const void *Src, size_t N) { + char *Tmp = (char *)malloc(N); + char *D = (char *)Dest; + const char *S = (const char *)Src; + + for (size_t I = 0; I < N; ++I) + Tmp[I] = S[I]; + for (size_t I = 0; I < N; ++I) + D[I] = Tmp[I]; + + free(Tmp); + return Dest; +} + +int main() { + __hwasan_enable_allocator_tagging(); + + const size_t BufSize = 64; + char *Buf = (char *)malloc(BufSize); + + for (size_t I = 0; I < BufSize; ++I) + Buf[I] = I; + memmove(Buf + BufSize / 2, Buf, BufSize / 2); + for (size_t I = 0; I < BufSize; ++I) + assert(Buf[I] == I % (BufSize / 2)); + + free(Buf); + return 0; +}