101 lines · cpp
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-exception6//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 17using LIBC_NAMESPACE::cpp::array;18using LIBC_NAMESPACE::cpp::span;19 20namespace LIBC_NAMESPACE_DECL {21 22TEST(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 30TEST(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 38TEST(LlvmLibcBcopyTest, DstStartsBeforeSrc) {39 // Set boundary at beginning and end for not overstepping when40 // 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 48TEST(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__]60TEST(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 68TEST(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.77static 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 82TEST(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(91 CheckMemmove<Adaptor>(Buffer, static_cast<size_t>(Size), Overlap));92 // Prevent quadratic behavior by skipping offset above kDenseOverlap.93 if (Overlap > kDenseOverlap)94 Overlap *= 2;95 else96 ++Overlap;97 }98}99 100} // namespace LIBC_NAMESPACE_DECL101