• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 using LIBC_NAMESPACE::cpp::array;
17 using LIBC_NAMESPACE::cpp::span;
18 
19 namespace LIBC_NAMESPACE {
20 
TEST(LlvmLibcBcopyTest,MoveZeroByte)21 TEST(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(Buffer + 2, Dst, 0);
26   ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
27 }
28 
TEST(LlvmLibcBcopyTest,DstAndSrcPointToSameAddress)29 TEST(LlvmLibcBcopyTest, DstAndSrcPointToSameAddress) {
30   char Buffer[] = {'a', 'b'};
31   const char Expected[] = {'a', 'b'};
32   void *const Dst = Buffer;
33   LIBC_NAMESPACE::bcopy(Buffer, Dst, 1);
34   ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
35 }
36 
TEST(LlvmLibcBcopyTest,DstStartsBeforeSrc)37 TEST(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(Buffer + 2, Dst, 2);
44   ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
45 }
46 
TEST(LlvmLibcBcopyTest,DstStartsAfterSrc)47 TEST(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(Buffer + 1, Dst, 2);
52   ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
53 }
54 
55 // e.g. `Dst` follow `src`.
56 // str: [abcdefghij]
57 //      [__src_____]
58 //      [_____Dst__]
TEST(LlvmLibcBcopyTest,SrcFollowDst)59 TEST(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(Buffer + 2, Dst, 1);
64   ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
65 }
66 
TEST(LlvmLibcBcopyTest,DstFollowSrc)67 TEST(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(Buffer + 1, Dst, 1);
72   ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
73 }
74 
75 // Adapt CheckMemmove signature to bcopy.
Adaptor(cpp::span<char> dst,cpp::span<char> src,size_t size)76 static inline void Adaptor(cpp::span<char> dst, cpp::span<char> src,
77                            size_t size) {
78   LIBC_NAMESPACE::bcopy(src.begin(), dst.begin(), size);
79 }
80 
TEST(LlvmLibcBcopyTest,SizeSweep)81 TEST(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);
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