16ca54e01SGuillaume Chatelet //===-- Unittests for memcpy ----------------------------------------------===//
204a309ddSGuillaume Chatelet //
304a309ddSGuillaume Chatelet // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
404a309ddSGuillaume Chatelet // See https://llvm.org/LICENSE.txt for license information.
504a309ddSGuillaume Chatelet // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
604a309ddSGuillaume Chatelet //
704a309ddSGuillaume Chatelet //===----------------------------------------------------------------------===//
804a309ddSGuillaume Chatelet
9f362aea4SSiva Chandra Reddy #include "src/__support/CPP/ArrayRef.h"
106ca54e01SGuillaume Chatelet #include "src/string/memcpy.h"
1104a309ddSGuillaume Chatelet #include "utils/UnitTest/Test.h"
1204a309ddSGuillaume Chatelet
1304a309ddSGuillaume Chatelet using __llvm_libc::cpp::Array;
1404a309ddSGuillaume Chatelet using __llvm_libc::cpp::ArrayRef;
1504a309ddSGuillaume Chatelet using Data = Array<char, 2048>;
1604a309ddSGuillaume Chatelet
17*25226f3eSMichael Jones static const ArrayRef<char> k_numbers("0123456789", 10);
18*25226f3eSMichael Jones static const ArrayRef<char> k_deadcode("DEADC0DE", 8);
1904a309ddSGuillaume Chatelet
2004a309ddSGuillaume Chatelet // Returns a Data object filled with a repetition of `filler`.
get_data(ArrayRef<char> filler)21*25226f3eSMichael Jones Data get_data(ArrayRef<char> filler) {
2204a309ddSGuillaume Chatelet Data out;
2304a309ddSGuillaume Chatelet for (size_t i = 0; i < out.size(); ++i)
2404a309ddSGuillaume Chatelet out[i] = filler[i % filler.size()];
2504a309ddSGuillaume Chatelet return out;
2604a309ddSGuillaume Chatelet }
2704a309ddSGuillaume Chatelet
TEST(LlvmLibcMemcpyTest,Thorough)281df0dbfcSMichael Jones TEST(LlvmLibcMemcpyTest, Thorough) {
29*25226f3eSMichael Jones const Data groundtruth = get_data(k_numbers);
30*25226f3eSMichael Jones const Data dirty = get_data(k_deadcode);
3104a309ddSGuillaume Chatelet for (size_t count = 0; count < 1024; ++count) {
3204a309ddSGuillaume Chatelet for (size_t align = 0; align < 64; ++align) {
3304a309ddSGuillaume Chatelet auto buffer = dirty;
3404a309ddSGuillaume Chatelet const char *const src = groundtruth.data();
356ca54e01SGuillaume Chatelet void *const dst = &buffer[align];
366ca54e01SGuillaume Chatelet void *const ret = __llvm_libc::memcpy(dst, src, count);
376ca54e01SGuillaume Chatelet // Return value is `dst`.
386ca54e01SGuillaume Chatelet ASSERT_EQ(ret, dst);
3904a309ddSGuillaume Chatelet // Everything before copy is untouched.
4004a309ddSGuillaume Chatelet for (size_t i = 0; i < align; ++i)
4104a309ddSGuillaume Chatelet ASSERT_EQ(buffer[i], dirty[i]);
4204a309ddSGuillaume Chatelet // Everything in between is copied.
4304a309ddSGuillaume Chatelet for (size_t i = 0; i < count; ++i)
4404a309ddSGuillaume Chatelet ASSERT_EQ(buffer[align + i], groundtruth[i]);
4504a309ddSGuillaume Chatelet // Everything after copy is untouched.
4604a309ddSGuillaume Chatelet for (size_t i = align + count; i < dirty.size(); ++i)
4704a309ddSGuillaume Chatelet ASSERT_EQ(buffer[i], dirty[i]);
4804a309ddSGuillaume Chatelet }
4904a309ddSGuillaume Chatelet }
5004a309ddSGuillaume Chatelet }
5104a309ddSGuillaume Chatelet
5204a309ddSGuillaume Chatelet // FIXME: Add tests with reads and writes on the boundary of a read/write
5304a309ddSGuillaume Chatelet // protected page to check we're not reading nor writing prior/past the allowed
5404a309ddSGuillaume Chatelet // regions.
55