summaryrefslogtreecommitdiff
path: root/libc/test/src/string/memmove_test.cpp
blob: b922fb4d5dd445296b362b78701d55f86569273c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//===-- Unittests for memmove ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/__support/CPP/ArrayRef.h"
#include "src/string/memmove.h"
#include "utils/UnitTest/Test.h"

class LlvmLibcMemmoveTest : public __llvm_libc::testing::Test {
public:
  void check_memmove(void *dst, const void *src, size_t count,
                     const unsigned char *str,
                     const __llvm_libc::cpp::ArrayRef<unsigned char> expected) {
    void *result = __llvm_libc::memmove(dst, src, count);
    // Making sure the pointer returned is same with `dst`.
    EXPECT_EQ(result, dst);
    // `expected` is designed according to `str`.
    // `dst` and `src` might be part of `str`.
    // Making sure `str` is same with `expected`.
    for (size_t i = 0; i < expected.size(); ++i)
      EXPECT_EQ(str[i], expected[i]);
  }
};

TEST_F(LlvmLibcMemmoveTest, MoveZeroByte) {
  unsigned char dst[] = {'a', 'b'};
  const unsigned char src[] = {'y', 'z'};
  const unsigned char expected[] = {'a', 'b'};
  check_memmove(dst, src, 0, dst, expected);
}

TEST_F(LlvmLibcMemmoveTest, OverlapThatDstAndSrcPointToSameAddress) {
  unsigned char str[] = {'a', 'b'};
  const unsigned char expected[] = {'a', 'b'};
  check_memmove(str, str, 1, str, expected);
}

TEST_F(LlvmLibcMemmoveTest, OverlapThatDstStartsBeforeSrc) {
  // Set boundary at beginning and end for not overstepping when
  // copy forward or backward.
  unsigned char str[] = {'z', 'a', 'b', 'c', 'z'};
  const unsigned char expected[] = {'z', 'b', 'c', 'c', 'z'};
  // `dst` is `&str[1]`.
  check_memmove(&str[1], &str[2], 2, str, expected);
}

TEST_F(LlvmLibcMemmoveTest, OverlapThatDstStartsAfterSrc) {
  unsigned char str[] = {'z', 'a', 'b', 'c', 'z'};
  const unsigned char expected[] = {'z', 'a', 'a', 'b', 'z'};
  check_memmove(&str[2], &str[1], 2, str, expected);
}

// e.g. `dst` follow `src`.
// str: [abcdefghij]
//      [__src_____]
//      [_____dst__]
TEST_F(LlvmLibcMemmoveTest, SrcFollowDst) {
  unsigned char str[] = {'z', 'a', 'b', 'z'};
  const unsigned char expected[] = {'z', 'b', 'b', 'z'};
  check_memmove(&str[1], &str[2], 1, str, expected);
}

TEST_F(LlvmLibcMemmoveTest, DstFollowSrc) {
  unsigned char str[] = {'z', 'a', 'b', 'z'};
  const unsigned char expected[] = {'z', 'a', 'a', 'z'};
  check_memmove(&str[2], &str[1], 1, str, expected);
}