xref: /aosp_15_r20/external/llvm-libc/test/src/string/bcopy_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
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/__support/macros/config.h"
10 #include "src/string/bcopy.h"
11 
12 #include "memory_utils/memory_check_utils.h"
13 #include "src/__support/CPP/span.h"
14 #include "test/UnitTest/MemoryMatcher.h"
15 #include "test/UnitTest/Test.h"
16 
17 using LIBC_NAMESPACE::cpp::array;
18 using LIBC_NAMESPACE::cpp::span;
19 
20 namespace LIBC_NAMESPACE_DECL {
21 
TEST(LlvmLibcBcopyTest,MoveZeroByte)22 TEST(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 
TEST(LlvmLibcBcopyTest,DstAndSrcPointToSameAddress)30 TEST(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 
TEST(LlvmLibcBcopyTest,DstStartsBeforeSrc)38 TEST(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 
TEST(LlvmLibcBcopyTest,DstStartsAfterSrc)48 TEST(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__]
TEST(LlvmLibcBcopyTest,SrcFollowDst)60 TEST(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 
TEST(LlvmLibcBcopyTest,DstFollowSrc)68 TEST(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.
Adaptor(cpp::span<char> dst,cpp::span<char> src,size_t size)77 static 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 
TEST(LlvmLibcBcopyTest,SizeSweep)82 TEST(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(CheckMemmove<Adaptor>(Buffer, Size, Overlap));
91       // Prevent quadratic behavior by skipping offset above kDenseOverlap.
92       if (Overlap > kDenseOverlap)
93         Overlap *= 2;
94       else
95         ++Overlap;
96     }
97 }
98 
99 } // namespace LIBC_NAMESPACE_DECL
100