146044a69SEvgenii Stepanov //===-- iterate.cpp ---------------------------------------------*- C++ -*-===//
246044a69SEvgenii Stepanov //
346044a69SEvgenii Stepanov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
446044a69SEvgenii Stepanov // See https://llvm.org/LICENSE.txt for license information.
546044a69SEvgenii Stepanov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
646044a69SEvgenii Stepanov //
746044a69SEvgenii Stepanov //===----------------------------------------------------------------------===//
846044a69SEvgenii Stepanov
946044a69SEvgenii Stepanov #include "gwp_asan/tests/harness.h"
1046044a69SEvgenii Stepanov
11*4961bb47SGulfem Savrun Yeniceri #include <algorithm>
125556616bSKostya Kortchinsky #include <set>
135556616bSKostya Kortchinsky #include <vector>
145556616bSKostya Kortchinsky
TEST_F(CustomGuardedPoolAllocator,Iterate)1546044a69SEvgenii Stepanov TEST_F(CustomGuardedPoolAllocator, Iterate) {
1646044a69SEvgenii Stepanov InitNumSlots(7);
1746044a69SEvgenii Stepanov std::vector<std::pair<void *, size_t>> Allocated;
1846044a69SEvgenii Stepanov auto alloc = [&](size_t size) {
1946044a69SEvgenii Stepanov Allocated.push_back({GPA.allocate(size), size});
2046044a69SEvgenii Stepanov };
2146044a69SEvgenii Stepanov
2246044a69SEvgenii Stepanov void *Ptr = GPA.allocate(5);
2346044a69SEvgenii Stepanov alloc(2);
2446044a69SEvgenii Stepanov alloc(1);
2546044a69SEvgenii Stepanov alloc(100);
2646044a69SEvgenii Stepanov GPA.deallocate(Ptr);
2746044a69SEvgenii Stepanov alloc(42);
2846044a69SEvgenii Stepanov std::sort(Allocated.begin(), Allocated.end());
2946044a69SEvgenii Stepanov
3046044a69SEvgenii Stepanov GPA.disable();
3146044a69SEvgenii Stepanov void *Base = Allocated[0].first;
3246044a69SEvgenii Stepanov size_t Size = reinterpret_cast<size_t>(Allocated.back().first) -
3346044a69SEvgenii Stepanov reinterpret_cast<size_t>(Base) + 1;
3446044a69SEvgenii Stepanov std::vector<std::pair<void *, size_t>> Found;
3546044a69SEvgenii Stepanov GPA.iterate(
3646044a69SEvgenii Stepanov Base, Size,
3746044a69SEvgenii Stepanov [](uintptr_t Addr, size_t Size, void *Arg) {
3846044a69SEvgenii Stepanov reinterpret_cast<std::vector<std::pair<void *, size_t>> *>(Arg)
3946044a69SEvgenii Stepanov ->push_back({(void *)Addr, Size});
4046044a69SEvgenii Stepanov },
4146044a69SEvgenii Stepanov reinterpret_cast<void *>(&Found));
4246044a69SEvgenii Stepanov GPA.enable();
4346044a69SEvgenii Stepanov
4446044a69SEvgenii Stepanov std::sort(Found.begin(), Found.end());
4546044a69SEvgenii Stepanov EXPECT_EQ(Allocated, Found);
4646044a69SEvgenii Stepanov
4746044a69SEvgenii Stepanov // Now without the last allocation.
4846044a69SEvgenii Stepanov GPA.disable();
4946044a69SEvgenii Stepanov Size = reinterpret_cast<size_t>(Allocated.back().first) -
5046044a69SEvgenii Stepanov reinterpret_cast<size_t>(Base); // Allocated.back() is out of range.
5146044a69SEvgenii Stepanov Found.clear();
5246044a69SEvgenii Stepanov GPA.iterate(
5346044a69SEvgenii Stepanov Base, Size,
5446044a69SEvgenii Stepanov [](uintptr_t Addr, size_t Size, void *Arg) {
5546044a69SEvgenii Stepanov reinterpret_cast<std::vector<std::pair<void *, size_t>> *>(Arg)
5646044a69SEvgenii Stepanov ->push_back({(void *)Addr, Size});
5746044a69SEvgenii Stepanov },
5846044a69SEvgenii Stepanov reinterpret_cast<void *>(&Found));
5946044a69SEvgenii Stepanov GPA.enable();
6046044a69SEvgenii Stepanov
6146044a69SEvgenii Stepanov // We should have found every allocation but the last.
6246044a69SEvgenii Stepanov // Remove it and compare the rest.
6346044a69SEvgenii Stepanov std::sort(Found.begin(), Found.end());
6446044a69SEvgenii Stepanov GPA.deallocate(Allocated.back().first);
6546044a69SEvgenii Stepanov Allocated.pop_back();
6646044a69SEvgenii Stepanov EXPECT_EQ(Allocated, Found);
6746044a69SEvgenii Stepanov
6846044a69SEvgenii Stepanov for (auto PS : Allocated)
6946044a69SEvgenii Stepanov GPA.deallocate(PS.first);
7046044a69SEvgenii Stepanov }
71