Fix the internal_memmove() implementation that used to skip src[0] if dst < src.
authorAlexander Potapenko <glider@google.com>
Fri, 26 Oct 2012 13:24:20 +0000 (13:24 +0000)
committerAlexander Potapenko <glider@google.com>
Fri, 26 Oct 2012 13:24:20 +0000 (13:24 +0000)
llvm-svn: 166774

compiler-rt/lib/sanitizer_common/sanitizer_libc.cc
compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt
compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc [new file with mode: 0644]

index cb36d2c..537c30b 100644 (file)
@@ -47,13 +47,14 @@ void *internal_memcpy(void *dest, const void *src, uptr n) {
 void *internal_memmove(void *dest, const void *src, uptr n) {
   char *d = (char*)dest;
   char *s = (char*)src;
-  uptr i;
+  sptr i = (sptr)n;
+  CHECK_GE(i, 0);
   if (d < s) {
     for (i = 0; i < n; ++i)
       d[i] = s[i];
   } else {
     if (d > s && n > 0)
-      for (i = n - 1; i > 0 ; --i) {
+      for (i = n - 1; i >= 0 ; --i) {
         d[i] = s[i];
       }
   }
index a4c4707..d4debc9 100644 (file)
@@ -2,6 +2,7 @@ set(SANITIZER_UNITTESTS
   sanitizer_allocator_test.cc
   sanitizer_common_test.cc
   sanitizer_flags_test.cc
+  sanitizer_libc_test.cc
   sanitizer_list_test.cc
   sanitizer_stackdepot_test.cc
   sanitizer_test_main.cc
diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc
new file mode 100644 (file)
index 0000000..ff38e16
--- /dev/null
@@ -0,0 +1,22 @@
+//===-- sanitizer_libc_test.cc --------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Tests for sanitizer_libc.h.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_common/sanitizer_libc.h"
+#include "gtest/gtest.h"
+
+// A regression test for internal_memmove() implementation.
+TEST(SanitizerCommon, InternalMemmoveRegression) {
+  char src[] = "Hello World";
+  char *dest = src + 6;
+  __sanitizer::internal_memmove(dest, src, 5);
+  EXPECT_EQ(dest[0], src[0]);
+  EXPECT_EQ(dest[4], src[4]);
+}