1*71db0c75SAndroid Build Coastguard Worker //===-- Unittests for memmove ---------------------------------------------===//
2*71db0c75SAndroid Build Coastguard Worker //
3*71db0c75SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*71db0c75SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information.
5*71db0c75SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*71db0c75SAndroid Build Coastguard Worker //
7*71db0c75SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
8*71db0c75SAndroid Build Coastguard Worker
9*71db0c75SAndroid Build Coastguard Worker #include "src/__support/macros/config.h"
10*71db0c75SAndroid Build Coastguard Worker #include "src/string/memmove.h"
11*71db0c75SAndroid Build Coastguard Worker
12*71db0c75SAndroid Build Coastguard Worker #include "memory_utils/memory_check_utils.h"
13*71db0c75SAndroid Build Coastguard Worker #include "src/__support/CPP/span.h"
14*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/MemoryMatcher.h"
15*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/Test.h"
16*71db0c75SAndroid Build Coastguard Worker
17*71db0c75SAndroid Build Coastguard Worker using LIBC_NAMESPACE::cpp::array;
18*71db0c75SAndroid Build Coastguard Worker using LIBC_NAMESPACE::cpp::span;
19*71db0c75SAndroid Build Coastguard Worker
20*71db0c75SAndroid Build Coastguard Worker namespace LIBC_NAMESPACE_DECL {
21*71db0c75SAndroid Build Coastguard Worker
TEST(LlvmLibcMemmoveTest,MoveZeroByte)22*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcMemmoveTest, MoveZeroByte) {
23*71db0c75SAndroid Build Coastguard Worker char Buffer[] = {'a', 'b', 'y', 'z'};
24*71db0c75SAndroid Build Coastguard Worker const char Expected[] = {'a', 'b', 'y', 'z'};
25*71db0c75SAndroid Build Coastguard Worker void *const Dst = Buffer;
26*71db0c75SAndroid Build Coastguard Worker void *const Ret = LIBC_NAMESPACE::memmove(Dst, Buffer + 2, 0);
27*71db0c75SAndroid Build Coastguard Worker EXPECT_EQ(Ret, Dst);
28*71db0c75SAndroid Build Coastguard Worker ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
29*71db0c75SAndroid Build Coastguard Worker }
30*71db0c75SAndroid Build Coastguard Worker
TEST(LlvmLibcMemmoveTest,DstAndSrcPointToSameAddress)31*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcMemmoveTest, DstAndSrcPointToSameAddress) {
32*71db0c75SAndroid Build Coastguard Worker char Buffer[] = {'a', 'b'};
33*71db0c75SAndroid Build Coastguard Worker const char Expected[] = {'a', 'b'};
34*71db0c75SAndroid Build Coastguard Worker void *const Dst = Buffer;
35*71db0c75SAndroid Build Coastguard Worker void *const Ret = LIBC_NAMESPACE::memmove(Dst, Buffer, 1);
36*71db0c75SAndroid Build Coastguard Worker EXPECT_EQ(Ret, Dst);
37*71db0c75SAndroid Build Coastguard Worker ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
38*71db0c75SAndroid Build Coastguard Worker }
39*71db0c75SAndroid Build Coastguard Worker
TEST(LlvmLibcMemmoveTest,DstStartsBeforeSrc)40*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcMemmoveTest, DstStartsBeforeSrc) {
41*71db0c75SAndroid Build Coastguard Worker // Set boundary at beginning and end for not overstepping when
42*71db0c75SAndroid Build Coastguard Worker // copy forward or backward.
43*71db0c75SAndroid Build Coastguard Worker char Buffer[] = {'z', 'a', 'b', 'c', 'z'};
44*71db0c75SAndroid Build Coastguard Worker const char Expected[] = {'z', 'b', 'c', 'c', 'z'};
45*71db0c75SAndroid Build Coastguard Worker void *const Dst = Buffer + 1;
46*71db0c75SAndroid Build Coastguard Worker void *const Ret = LIBC_NAMESPACE::memmove(Dst, Buffer + 2, 2);
47*71db0c75SAndroid Build Coastguard Worker EXPECT_EQ(Ret, Dst);
48*71db0c75SAndroid Build Coastguard Worker ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
49*71db0c75SAndroid Build Coastguard Worker }
50*71db0c75SAndroid Build Coastguard Worker
TEST(LlvmLibcMemmoveTest,DstStartsAfterSrc)51*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcMemmoveTest, DstStartsAfterSrc) {
52*71db0c75SAndroid Build Coastguard Worker char Buffer[] = {'z', 'a', 'b', 'c', 'z'};
53*71db0c75SAndroid Build Coastguard Worker const char Expected[] = {'z', 'a', 'a', 'b', 'z'};
54*71db0c75SAndroid Build Coastguard Worker void *const Dst = Buffer + 2;
55*71db0c75SAndroid Build Coastguard Worker void *const Ret = LIBC_NAMESPACE::memmove(Dst, Buffer + 1, 2);
56*71db0c75SAndroid Build Coastguard Worker EXPECT_EQ(Ret, Dst);
57*71db0c75SAndroid Build Coastguard Worker ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
58*71db0c75SAndroid Build Coastguard Worker }
59*71db0c75SAndroid Build Coastguard Worker
60*71db0c75SAndroid Build Coastguard Worker // e.g. `Dst` follow `src`.
61*71db0c75SAndroid Build Coastguard Worker // str: [abcdefghij]
62*71db0c75SAndroid Build Coastguard Worker // [__src_____]
63*71db0c75SAndroid Build Coastguard Worker // [_____Dst__]
TEST(LlvmLibcMemmoveTest,SrcFollowDst)64*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcMemmoveTest, SrcFollowDst) {
65*71db0c75SAndroid Build Coastguard Worker char Buffer[] = {'z', 'a', 'b', 'z'};
66*71db0c75SAndroid Build Coastguard Worker const char Expected[] = {'z', 'b', 'b', 'z'};
67*71db0c75SAndroid Build Coastguard Worker void *const Dst = Buffer + 1;
68*71db0c75SAndroid Build Coastguard Worker void *const Ret = LIBC_NAMESPACE::memmove(Dst, Buffer + 2, 1);
69*71db0c75SAndroid Build Coastguard Worker EXPECT_EQ(Ret, Dst);
70*71db0c75SAndroid Build Coastguard Worker ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
71*71db0c75SAndroid Build Coastguard Worker }
72*71db0c75SAndroid Build Coastguard Worker
TEST(LlvmLibcMemmoveTest,DstFollowSrc)73*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcMemmoveTest, DstFollowSrc) {
74*71db0c75SAndroid Build Coastguard Worker char Buffer[] = {'z', 'a', 'b', 'z'};
75*71db0c75SAndroid Build Coastguard Worker const char Expected[] = {'z', 'a', 'a', 'z'};
76*71db0c75SAndroid Build Coastguard Worker void *const Dst = Buffer + 2;
77*71db0c75SAndroid Build Coastguard Worker void *const Ret = LIBC_NAMESPACE::memmove(Dst, Buffer + 1, 1);
78*71db0c75SAndroid Build Coastguard Worker EXPECT_EQ(Ret, Dst);
79*71db0c75SAndroid Build Coastguard Worker ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
80*71db0c75SAndroid Build Coastguard Worker }
81*71db0c75SAndroid Build Coastguard Worker
82*71db0c75SAndroid Build Coastguard Worker // Adapt CheckMemmove signature to op implementation signatures.
Adaptor(cpp::span<char> dst,cpp::span<char> src,size_t size)83*71db0c75SAndroid Build Coastguard Worker static inline void Adaptor(cpp::span<char> dst, cpp::span<char> src,
84*71db0c75SAndroid Build Coastguard Worker size_t size) {
85*71db0c75SAndroid Build Coastguard Worker LIBC_NAMESPACE::memmove(dst.begin(), src.begin(), size);
86*71db0c75SAndroid Build Coastguard Worker }
87*71db0c75SAndroid Build Coastguard Worker
TEST(LlvmLibcMemmoveTest,SizeSweep)88*71db0c75SAndroid Build Coastguard Worker TEST(LlvmLibcMemmoveTest, SizeSweep) {
89*71db0c75SAndroid Build Coastguard Worker static constexpr int kMaxSize = 400;
90*71db0c75SAndroid Build Coastguard Worker static constexpr int kDenseOverlap = 15;
91*71db0c75SAndroid Build Coastguard Worker using LargeBuffer = array<char, 2 * kMaxSize + 1>;
92*71db0c75SAndroid Build Coastguard Worker LargeBuffer Buffer;
93*71db0c75SAndroid Build Coastguard Worker Randomize(Buffer);
94*71db0c75SAndroid Build Coastguard Worker for (int Size = 0; Size < kMaxSize; ++Size)
95*71db0c75SAndroid Build Coastguard Worker for (int Overlap = -1; Overlap < Size;) {
96*71db0c75SAndroid Build Coastguard Worker ASSERT_TRUE(CheckMemmove<Adaptor>(Buffer, Size, Overlap));
97*71db0c75SAndroid Build Coastguard Worker // Prevent quadratic behavior by skipping offset above kDenseOverlap.
98*71db0c75SAndroid Build Coastguard Worker if (Overlap > kDenseOverlap)
99*71db0c75SAndroid Build Coastguard Worker Overlap *= 2;
100*71db0c75SAndroid Build Coastguard Worker else
101*71db0c75SAndroid Build Coastguard Worker ++Overlap;
102*71db0c75SAndroid Build Coastguard Worker }
103*71db0c75SAndroid Build Coastguard Worker }
104*71db0c75SAndroid Build Coastguard Worker
105*71db0c75SAndroid Build Coastguard Worker } // namespace LIBC_NAMESPACE_DECL
106