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

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