1//===-- Unittests for bcopy -----------------------------------------------===//
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/bcopy.h"
10
11#include "memory_utils/memory_check_utils.h"
12#include "src/__support/CPP/span.h"
13#include "test/UnitTest/MemoryMatcher.h"
14#include "test/UnitTest/Test.h"
15
16using LIBC_NAMESPACE::cpp::array;
17using LIBC_NAMESPACE::cpp::span;
18
19namespace LIBC_NAMESPACE {
20
21TEST(LlvmLibcBcopyTest, MoveZeroByte) {
22 char Buffer[] = {'a', 'b', 'y', 'z'};
23 const char Expected[] = {'a', 'b', 'y', 'z'};
24 void *const Dst = Buffer;
25 LIBC_NAMESPACE::bcopy(src: Buffer + 2, dest: Dst, count: 0);
26 ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
27}
28
29TEST(LlvmLibcBcopyTest, DstAndSrcPointToSameAddress) {
30 char Buffer[] = {'a', 'b'};
31 const char Expected[] = {'a', 'b'};
32 void *const Dst = Buffer;
33 LIBC_NAMESPACE::bcopy(src: Buffer, dest: Dst, count: 1);
34 ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
35}
36
37TEST(LlvmLibcBcopyTest, DstStartsBeforeSrc) {
38 // Set boundary at beginning and end for not overstepping when
39 // copy forward or backward.
40 char Buffer[] = {'z', 'a', 'b', 'c', 'z'};
41 const char Expected[] = {'z', 'b', 'c', 'c', 'z'};
42 void *const Dst = Buffer + 1;
43 LIBC_NAMESPACE::bcopy(src: Buffer + 2, dest: Dst, count: 2);
44 ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
45}
46
47TEST(LlvmLibcBcopyTest, DstStartsAfterSrc) {
48 char Buffer[] = {'z', 'a', 'b', 'c', 'z'};
49 const char Expected[] = {'z', 'a', 'a', 'b', 'z'};
50 void *const Dst = Buffer + 2;
51 LIBC_NAMESPACE::bcopy(src: Buffer + 1, dest: Dst, count: 2);
52 ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
53}
54
55// e.g. `Dst` follow `src`.
56// str: [abcdefghij]
57// [__src_____]
58// [_____Dst__]
59TEST(LlvmLibcBcopyTest, SrcFollowDst) {
60 char Buffer[] = {'z', 'a', 'b', 'z'};
61 const char Expected[] = {'z', 'b', 'b', 'z'};
62 void *const Dst = Buffer + 1;
63 LIBC_NAMESPACE::bcopy(src: Buffer + 2, dest: Dst, count: 1);
64 ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
65}
66
67TEST(LlvmLibcBcopyTest, DstFollowSrc) {
68 char Buffer[] = {'z', 'a', 'b', 'z'};
69 const char Expected[] = {'z', 'a', 'a', 'z'};
70 void *const Dst = Buffer + 2;
71 LIBC_NAMESPACE::bcopy(src: Buffer + 1, dest: Dst, count: 1);
72 ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
73}
74
75// Adapt CheckMemmove signature to bcopy.
76static inline void Adaptor(cpp::span<char> dst, cpp::span<char> src,
77 size_t size) {
78 LIBC_NAMESPACE::bcopy(src: src.begin(), dest: dst.begin(), count: size);
79}
80
81TEST(LlvmLibcBcopyTest, SizeSweep) {
82 static constexpr int kMaxSize = 400;
83 static constexpr int kDenseOverlap = 15;
84 using LargeBuffer = array<char, 2 * kMaxSize + 1>;
85 LargeBuffer Buffer;
86 Randomize(buffer: Buffer);
87 for (int Size = 0; Size < kMaxSize; ++Size)
88 for (int Overlap = -1; Overlap < Size;) {
89 ASSERT_TRUE(CheckMemmove<Adaptor>(Buffer, Size, Overlap));
90 // Prevent quadratic behavior by skipping offset above kDenseOverlap.
91 if (Overlap > kDenseOverlap)
92 Overlap *= 2;
93 else
94 ++Overlap;
95 }
96}
97
98} // namespace LIBC_NAMESPACE
99

source code of libc/test/src/string/bcopy_test.cpp