1 //===-- Unittests for memmove ---------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "src/string/memmove.h"
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"
16 using __llvm_libc::cpp::array
;
17 using __llvm_libc::cpp::span
;
19 namespace __llvm_libc
{
21 TEST(LlvmLibcMemmoveTest
, MoveZeroByte
) {
22 char Buffer
[] = {'a', 'b', 'y', 'z'};
23 const char Expected
[] = {'a', 'b', 'y', 'z'};
24 void *const Dst
= Buffer
;
25 void *const Ret
= __llvm_libc::memmove(Dst
, Buffer
+ 2, 0);
27 ASSERT_MEM_EQ(Buffer
, testing::MemoryView(Expected
));
30 TEST(LlvmLibcMemmoveTest
, DstAndSrcPointToSameAddress
) {
31 char Buffer
[] = {'a', 'b'};
32 const char Expected
[] = {'a', 'b'};
33 void *const Dst
= Buffer
;
34 void *const Ret
= __llvm_libc::memmove(Dst
, Buffer
, 1);
36 ASSERT_MEM_EQ(Buffer
, testing::MemoryView(Expected
));
39 TEST(LlvmLibcMemmoveTest
, DstStartsBeforeSrc
) {
40 // Set boundary at beginning and end for not overstepping when
41 // copy forward or backward.
42 char Buffer
[] = {'z', 'a', 'b', 'c', 'z'};
43 const char Expected
[] = {'z', 'b', 'c', 'c', 'z'};
44 void *const Dst
= Buffer
+ 1;
45 void *const Ret
= __llvm_libc::memmove(Dst
, Buffer
+ 2, 2);
47 ASSERT_MEM_EQ(Buffer
, testing::MemoryView(Expected
));
50 TEST(LlvmLibcMemmoveTest
, DstStartsAfterSrc
) {
51 char Buffer
[] = {'z', 'a', 'b', 'c', 'z'};
52 const char Expected
[] = {'z', 'a', 'a', 'b', 'z'};
53 void *const Dst
= Buffer
+ 2;
54 void *const Ret
= __llvm_libc::memmove(Dst
, Buffer
+ 1, 2);
56 ASSERT_MEM_EQ(Buffer
, testing::MemoryView(Expected
));
59 // e.g. `Dst` follow `src`.
63 TEST(LlvmLibcMemmoveTest
, SrcFollowDst
) {
64 char Buffer
[] = {'z', 'a', 'b', 'z'};
65 const char Expected
[] = {'z', 'b', 'b', 'z'};
66 void *const Dst
= Buffer
+ 1;
67 void *const Ret
= __llvm_libc::memmove(Dst
, Buffer
+ 2, 1);
69 ASSERT_MEM_EQ(Buffer
, testing::MemoryView(Expected
));
72 TEST(LlvmLibcMemmoveTest
, DstFollowSrc
) {
73 char Buffer
[] = {'z', 'a', 'b', 'z'};
74 const char Expected
[] = {'z', 'a', 'a', 'z'};
75 void *const Dst
= Buffer
+ 2;
76 void *const Ret
= __llvm_libc::memmove(Dst
, Buffer
+ 1, 1);
78 ASSERT_MEM_EQ(Buffer
, testing::MemoryView(Expected
));
81 // Adapt CheckMemmove signature to op implementation signatures.
82 static inline void Adaptor(cpp::span
<char> dst
, cpp::span
<char> src
,
84 __llvm_libc::memmove(dst
.begin(), src
.begin(), size
);
87 TEST(LlvmLibcMemmoveTest
, SizeSweep
) {
88 static constexpr int kMaxSize
= 400;
89 static constexpr int kDenseOverlap
= 15;
90 using LargeBuffer
= array
<char, 2 * kMaxSize
+ 1>;
93 for (int Size
= 0; Size
< kMaxSize
; ++Size
)
94 for (int Overlap
= -1; Overlap
< Size
;) {
95 ASSERT_TRUE(CheckMemmove
<Adaptor
>(Buffer
, Size
, Overlap
));
96 // Prevent quadratic behavior by skipping offset above kDenseOverlap.
97 if (Overlap
> kDenseOverlap
)
104 } // namespace __llvm_libc