1 //===-- Unittests for memmove ---------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "src/string/memcmp.h"
10 #include "src/string/memmove.h"
11 #include "utils/CPP/ArrayRef.h"
12 #include "utils/UnitTest/Test.h"
13 
14 class LlvmLibcMemmoveTest : public __llvm_libc::testing::Test {
15 public:
16   void check_memmove(void *dest, const void *src, size_t count, const void *str,
17                      const __llvm_libc::cpp::ArrayRef<unsigned char> expected) {
18     void *result = __llvm_libc::memmove(dest, src, count);
19     // Making sure the pointer returned is same with dest.
20     EXPECT_EQ(result, dest);
21     // expected is designed according to str.
22     // dest and src might be part of str.
23     // Making sure the str is same with expected.
24     EXPECT_EQ(__llvm_libc::memcmp(str, expected.data(), expected.size()), 0);
25   }
26 };
27 
28 TEST_F(LlvmLibcMemmoveTest, MoveZeroByte) {
29   unsigned char dest[] = {'a', 'b'};
30   const unsigned char src[] = {'y', 'z'};
31   const unsigned char expected[] = {'a', 'b'};
32   check_memmove(dest, src, 0, dest, expected);
33 }
34 
35 TEST_F(LlvmLibcMemmoveTest, OverlapThatDestAndSrcPointToSameAddress) {
36   unsigned char str[] = {'a', 'b'};
37   const unsigned char expected[] = {'a', 'b'};
38   check_memmove(str, str, 1, str, expected);
39 }
40 
41 TEST_F(LlvmLibcMemmoveTest, OverlapThatDestStartsBeforeSrc) {
42   // Set boundary at beginning and end for not overstepping when
43   // copy forward or backward.
44   unsigned char str[] = {'z', 'a', 'b', 'c', 'z'};
45   const unsigned char expected[] = {'z', 'b', 'c', 'c', 'z'};
46   // dest is &str[1].
47   check_memmove(&str[1], &str[2], 2, str, expected);
48 }
49 
50 TEST_F(LlvmLibcMemmoveTest, OverlapThatDestStartsAfterSrc) {
51   unsigned char str[] = {'z', 'a', 'b', 'c', 'z'};
52   const unsigned char expected[] = {'z', 'a', 'a', 'b', 'z'};
53   check_memmove(&str[2], &str[1], 2, str, expected);
54 }
55 
56 // e.g. dest follow src.
57 // str: [abcdefghij]
58 //      [__src_____]
59 //      [_____dest_]
60 TEST_F(LlvmLibcMemmoveTest, SrcFollowDest) {
61   unsigned char str[] = {'z', 'a', 'b', 'z'};
62   const unsigned char expected[] = {'z', 'b', 'b', 'z'};
63   check_memmove(&str[1], &str[2], 1, str, expected);
64 }
65 
66 TEST_F(LlvmLibcMemmoveTest, DestFollowSrc) {
67   unsigned char str[] = {'z', 'a', 'b', 'z'};
68   const unsigned char expected[] = {'z', 'a', 'a', 'z'};
69   check_memmove(&str[2], &str[1], 1, str, expected);
70 }
71