11f9cb04fSpatrick //===-- iterate.cpp ---------------------------------------------*- C++ -*-===//
21f9cb04fSpatrick //
31f9cb04fSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41f9cb04fSpatrick // See https://llvm.org/LICENSE.txt for license information.
51f9cb04fSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61f9cb04fSpatrick //
71f9cb04fSpatrick //===----------------------------------------------------------------------===//
81f9cb04fSpatrick
91f9cb04fSpatrick #include "gwp_asan/tests/harness.h"
101f9cb04fSpatrick
11*810390e3Srobert #include <algorithm>
12d89ec533Spatrick #include <set>
13d89ec533Spatrick #include <vector>
14d89ec533Spatrick
TEST_F(CustomGuardedPoolAllocator,Iterate)151f9cb04fSpatrick TEST_F(CustomGuardedPoolAllocator, Iterate) {
161f9cb04fSpatrick InitNumSlots(7);
171f9cb04fSpatrick std::vector<std::pair<void *, size_t>> Allocated;
181f9cb04fSpatrick auto alloc = [&](size_t size) {
191f9cb04fSpatrick Allocated.push_back({GPA.allocate(size), size});
201f9cb04fSpatrick };
211f9cb04fSpatrick
221f9cb04fSpatrick void *Ptr = GPA.allocate(5);
231f9cb04fSpatrick alloc(2);
241f9cb04fSpatrick alloc(1);
251f9cb04fSpatrick alloc(100);
261f9cb04fSpatrick GPA.deallocate(Ptr);
271f9cb04fSpatrick alloc(42);
281f9cb04fSpatrick std::sort(Allocated.begin(), Allocated.end());
291f9cb04fSpatrick
301f9cb04fSpatrick GPA.disable();
311f9cb04fSpatrick void *Base = Allocated[0].first;
321f9cb04fSpatrick size_t Size = reinterpret_cast<size_t>(Allocated.back().first) -
331f9cb04fSpatrick reinterpret_cast<size_t>(Base) + 1;
341f9cb04fSpatrick std::vector<std::pair<void *, size_t>> Found;
351f9cb04fSpatrick GPA.iterate(
361f9cb04fSpatrick Base, Size,
371f9cb04fSpatrick [](uintptr_t Addr, size_t Size, void *Arg) {
381f9cb04fSpatrick reinterpret_cast<std::vector<std::pair<void *, size_t>> *>(Arg)
391f9cb04fSpatrick ->push_back({(void *)Addr, Size});
401f9cb04fSpatrick },
411f9cb04fSpatrick reinterpret_cast<void *>(&Found));
421f9cb04fSpatrick GPA.enable();
431f9cb04fSpatrick
441f9cb04fSpatrick std::sort(Found.begin(), Found.end());
451f9cb04fSpatrick EXPECT_EQ(Allocated, Found);
461f9cb04fSpatrick
471f9cb04fSpatrick // Now without the last allocation.
481f9cb04fSpatrick GPA.disable();
491f9cb04fSpatrick Size = reinterpret_cast<size_t>(Allocated.back().first) -
501f9cb04fSpatrick reinterpret_cast<size_t>(Base); // Allocated.back() is out of range.
511f9cb04fSpatrick Found.clear();
521f9cb04fSpatrick GPA.iterate(
531f9cb04fSpatrick Base, Size,
541f9cb04fSpatrick [](uintptr_t Addr, size_t Size, void *Arg) {
551f9cb04fSpatrick reinterpret_cast<std::vector<std::pair<void *, size_t>> *>(Arg)
561f9cb04fSpatrick ->push_back({(void *)Addr, Size});
571f9cb04fSpatrick },
581f9cb04fSpatrick reinterpret_cast<void *>(&Found));
591f9cb04fSpatrick GPA.enable();
601f9cb04fSpatrick
611f9cb04fSpatrick // We should have found every allocation but the last.
621f9cb04fSpatrick // Remove it and compare the rest.
631f9cb04fSpatrick std::sort(Found.begin(), Found.end());
641f9cb04fSpatrick GPA.deallocate(Allocated.back().first);
651f9cb04fSpatrick Allocated.pop_back();
661f9cb04fSpatrick EXPECT_EQ(Allocated, Found);
671f9cb04fSpatrick
681f9cb04fSpatrick for (auto PS : Allocated)
691f9cb04fSpatrick GPA.deallocate(PS.first);
701f9cb04fSpatrick }
71