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 17 using LIBC_NAMESPACE::cpp::array; 18 using LIBC_NAMESPACE::cpp::span; 19 20 namespace LIBC_NAMESPACE_DECL { 21 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 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 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 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__] 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 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. 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 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