1//===-- Unittests for memmove ---------------------------------------------===//
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 "hdr/signal_macros.h"
10#include "src/__support/macros/config.h"
11#include "src/string/memmove.h"
12
13#include "memory_utils/memory_check_utils.h"
14#include "src/__support/CPP/span.h"
15#include "test/UnitTest/MemoryMatcher.h"
16#include "test/UnitTest/Test.h"
17
18using LIBC_NAMESPACE::cpp::array;
19using LIBC_NAMESPACE::cpp::span;
20
21namespace LIBC_NAMESPACE_DECL {
22
23TEST(LlvmLibcMemmoveTest, MoveZeroByte) {
24 char Buffer[] = {'a', 'b', 'y', 'z'};
25 const char Expected[] = {'a', 'b', 'y', 'z'};
26 void *const Dst = Buffer;
27 void *const Ret = LIBC_NAMESPACE::memmove(Dst, Buffer + 2, 0);
28 EXPECT_EQ(Ret, Dst);
29 ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
30}
31
32TEST(LlvmLibcMemmoveTest, DstAndSrcPointToSameAddress) {
33 char Buffer[] = {'a', 'b'};
34 const char Expected[] = {'a', 'b'};
35 void *const Dst = Buffer;
36 void *const Ret = LIBC_NAMESPACE::memmove(Dst, Buffer, 1);
37 EXPECT_EQ(Ret, Dst);
38 ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
39}
40
41TEST(LlvmLibcMemmoveTest, DstStartsBeforeSrc) {
42 // Set boundary at beginning and end for not overstepping when
43 // copy forward or backward.
44 char Buffer[] = {'z', 'a', 'b', 'c', 'z'};
45 const char Expected[] = {'z', 'b', 'c', 'c', 'z'};
46 void *const Dst = Buffer + 1;
47 void *const Ret = LIBC_NAMESPACE::memmove(Dst, Buffer + 2, 2);
48 EXPECT_EQ(Ret, Dst);
49 ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
50}
51
52TEST(LlvmLibcMemmoveTest, DstStartsAfterSrc) {
53 char Buffer[] = {'z', 'a', 'b', 'c', 'z'};
54 const char Expected[] = {'z', 'a', 'a', 'b', 'z'};
55 void *const Dst = Buffer + 2;
56 void *const Ret = LIBC_NAMESPACE::memmove(Dst, Buffer + 1, 2);
57 EXPECT_EQ(Ret, Dst);
58 ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
59}
60
61// e.g. `Dst` follow `src`.
62// str: [abcdefghij]
63// [__src_____]
64// [_____Dst__]
65TEST(LlvmLibcMemmoveTest, SrcFollowDst) {
66 char Buffer[] = {'z', 'a', 'b', 'z'};
67 const char Expected[] = {'z', 'b', 'b', 'z'};
68 void *const Dst = Buffer + 1;
69 void *const Ret = LIBC_NAMESPACE::memmove(Dst, Buffer + 2, 1);
70 EXPECT_EQ(Ret, Dst);
71 ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
72}
73
74TEST(LlvmLibcMemmoveTest, DstFollowSrc) {
75 char Buffer[] = {'z', 'a', 'b', 'z'};
76 const char Expected[] = {'z', 'a', 'a', 'z'};
77 void *const Dst = Buffer + 2;
78 void *const Ret = LIBC_NAMESPACE::memmove(Dst, Buffer + 1, 1);
79 EXPECT_EQ(Ret, Dst);
80 ASSERT_MEM_EQ(Buffer, testing::MemoryView(Expected));
81}
82
83// Adapt CheckMemmove signature to op implementation signatures.
84static inline void Adaptor(cpp::span<char> dst, cpp::span<char> src,
85 size_t size) {
86 LIBC_NAMESPACE::memmove(dst.begin(), src.begin(), size);
87}
88
89TEST(LlvmLibcMemmoveTest, SizeSweep) {
90 static constexpr int kMaxSize = 400;
91 static constexpr int kDenseOverlap = 15;
92 using LargeBuffer = array<char, 2 * kMaxSize + 1>;
93 LargeBuffer Buffer;
94 Randomize(Buffer);
95 for (int Size = 0; Size < kMaxSize; ++Size)
96 for (int Overlap = -1; Overlap < Size;) {
97 ASSERT_TRUE(
98 CheckMemmove<Adaptor>(Buffer, static_cast<size_t>(Size), Overlap));
99 // Prevent quadratic behavior by skipping offset above kDenseOverlap.
100 if (Overlap > kDenseOverlap)
101 Overlap *= 2;
102 else
103 ++Overlap;
104 }
105}
106
107#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
108
109TEST(LlvmLibcMemmoveTest, CrashOnNullPtr) {
110 ASSERT_DEATH([]() { LIBC_NAMESPACE::memmove(nullptr, nullptr, 2); },
111 WITH_SIGNAL(-1));
112}
113
114#endif // LIBC_TARGET_OS_IS_LINUX
115
116} // namespace LIBC_NAMESPACE_DECL
117

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of libc/test/src/string/memmove_test.cpp