summaryrefslogtreecommitdiff
path: root/libc/test/src/string/bcopy_test.cpp
blob: affd23b1bd8b10d2a0f507d7da01d5eac8922204 (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//===-- Unittests for bcopy -----------------------------------------------===//
//
// 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/string/bcopy.h"

#include "memory_utils/memory_check_utils.h"
#include "src/__support/CPP/span.h"
#include "test/UnitTest/MemoryMatcher.h"
#include "test/UnitTest/Test.h"

using __llvm_libc::cpp::array;
using __llvm_libc::cpp::span;

TEST(LlvmLibcBcopyTest, MoveZeroByte) {
  char Buffer[] = {'a', 'b', 'y', 'z'};
  const char Expected[] = {'a', 'b', 'y', 'z'};
  void *const Dst = Buffer;
  __llvm_libc::bcopy(Buffer + 2, Dst, 0);
  ASSERT_MEM_EQ(Buffer, Expected);
}

TEST(LlvmLibcBcopyTest, DstAndSrcPointToSameAddress) {
  char Buffer[] = {'a', 'b'};
  const char Expected[] = {'a', 'b'};
  void *const Dst = Buffer;
  __llvm_libc::bcopy(Buffer, Dst, 1);
  ASSERT_MEM_EQ(Buffer, Expected);
}

TEST(LlvmLibcBcopyTest, DstStartsBeforeSrc) {
  // Set boundary at beginning and end for not overstepping when
  // copy forward or backward.
  char Buffer[] = {'z', 'a', 'b', 'c', 'z'};
  const char Expected[] = {'z', 'b', 'c', 'c', 'z'};
  void *const Dst = Buffer + 1;
  __llvm_libc::bcopy(Buffer + 2, Dst, 2);
  ASSERT_MEM_EQ(Buffer, Expected);
}

TEST(LlvmLibcBcopyTest, DstStartsAfterSrc) {
  char Buffer[] = {'z', 'a', 'b', 'c', 'z'};
  const char Expected[] = {'z', 'a', 'a', 'b', 'z'};
  void *const Dst = Buffer + 2;
  __llvm_libc::bcopy(Buffer + 1, Dst, 2);
  ASSERT_MEM_EQ(Buffer, Expected);
}

// e.g. `Dst` follow `src`.
// str: [abcdefghij]
//      [__src_____]
//      [_____Dst__]
TEST(LlvmLibcBcopyTest, SrcFollowDst) {
  char Buffer[] = {'z', 'a', 'b', 'z'};
  const char Expected[] = {'z', 'b', 'b', 'z'};
  void *const Dst = Buffer + 1;
  __llvm_libc::bcopy(Buffer + 2, Dst, 1);
  ASSERT_MEM_EQ(Buffer, Expected);
}

TEST(LlvmLibcBcopyTest, DstFollowSrc) {
  char Buffer[] = {'z', 'a', 'b', 'z'};
  const char Expected[] = {'z', 'a', 'a', 'z'};
  void *const Dst = Buffer + 2;
  __llvm_libc::bcopy(Buffer + 1, Dst, 1);
  ASSERT_MEM_EQ(Buffer, Expected);
}

static constexpr int kMaxSize = 512;

TEST(LlvmLibcBcopyTest, SizeSweep) {
  using LargeBuffer = array<char, 3 * kMaxSize>;
  LargeBuffer GroundTruth;
  __llvm_libc::Randomize(GroundTruth);
  for (int Size = 0; Size < kMaxSize; ++Size) {
    for (int Offset = -Size; Offset < Size; ++Offset) {
      LargeBuffer Buffer = GroundTruth;
      LargeBuffer Expected = GroundTruth;
      size_t DstOffset = kMaxSize;
      size_t SrcOffset = kMaxSize + Offset;
      for (int I = 0; I < Size; ++I)
        Expected[DstOffset + I] = GroundTruth[SrcOffset + I];
      void *const Dst = Buffer.data() + DstOffset;
      __llvm_libc::bcopy(Buffer.data() + SrcOffset, Dst, Size);
      ASSERT_MEM_EQ(Buffer, Expected);
    }
  }
}