1 //===-- list_test.cpp -------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "tests/scudo_unit_test.h"
15 struct ListItemLinkedWithPtr
{
16 ListItemLinkedWithPtr
*Next
;
17 ListItemLinkedWithPtr
*Prev
;
20 struct ListItemLinkedWithIndex
{
23 static constexpr scudo::uptr EndOfListVal
= 1ULL << 30;
26 template <typename ListT
, typename ListItemTy
>
27 static void setList(ListT
*L
, ListItemTy
*I1
= nullptr,
28 ListItemTy
*I2
= nullptr, ListItemTy
*I3
= nullptr) {
38 template <typename ListT
, typename ListItemTy
>
39 static void checkList(ListT
*L
, ListItemTy
*I1
, ListItemTy
*I2
= nullptr,
40 ListItemTy
*I3
= nullptr, ListItemTy
*I4
= nullptr,
41 ListItemTy
*I5
= nullptr, ListItemTy
*I6
= nullptr) {
43 EXPECT_EQ(L
->front(), I1
);
47 EXPECT_EQ(L
->front(), I2
);
51 EXPECT_EQ(L
->front(), I3
);
55 EXPECT_EQ(L
->front(), I4
);
59 EXPECT_EQ(L
->front(), I5
);
63 EXPECT_EQ(L
->front(), I6
);
66 EXPECT_TRUE(L
->empty());
69 template <template <typename
> class ListTy
, typename ListItemTy
>
70 static void testListCommon(void) {
72 ListItemTy
*X
= &Items
[0];
73 ListItemTy
*Y
= &Items
[1];
74 ListItemTy
*Z
= &Items
[2];
78 L
.init(Items
, sizeof(Items
));
80 EXPECT_EQ(L
.size(), 0U);
82 EXPECT_EQ(L
.size(), 1U);
83 EXPECT_EQ(L
.back(), X
);
84 EXPECT_EQ(L
.front(), X
);
86 EXPECT_TRUE(L
.empty());
90 EXPECT_EQ(L
.size(), 1U);
91 EXPECT_EQ(L
.back(), X
);
92 EXPECT_EQ(L
.front(), X
);
94 EXPECT_TRUE(L
.empty());
100 EXPECT_EQ(L
.size(), 3U);
101 EXPECT_EQ(L
.front(), Z
);
102 EXPECT_EQ(L
.back(), X
);
103 L
.checkConsistency();
106 EXPECT_EQ(L
.size(), 2U);
107 EXPECT_EQ(L
.front(), Y
);
108 EXPECT_EQ(L
.back(), X
);
111 EXPECT_TRUE(L
.empty());
112 L
.checkConsistency();
117 EXPECT_EQ(L
.size(), 3U);
118 EXPECT_EQ(L
.front(), X
);
119 EXPECT_EQ(L
.back(), Z
);
120 L
.checkConsistency();
123 EXPECT_EQ(L
.size(), 2U);
124 EXPECT_EQ(L
.front(), Y
);
125 EXPECT_EQ(L
.back(), Z
);
128 EXPECT_TRUE(L
.empty());
129 L
.checkConsistency();
135 // Verify the iterator
136 std::array
<ListItemTy
*, 3> visitOrder
{X
, Y
, Z
};
137 auto Iter
= visitOrder
.begin();
138 for (const auto &Item
: L
) {
139 EXPECT_EQ(&Item
, *Iter
);
144 TEST(ScudoListTest
, LinkedListCommon
) {
145 testListCommon
<scudo::SinglyLinkedList
, ListItemLinkedWithPtr
>();
146 testListCommon
<scudo::SinglyLinkedList
, ListItemLinkedWithIndex
>();
147 testListCommon
<scudo::DoublyLinkedList
, ListItemLinkedWithPtr
>();
148 testListCommon
<scudo::DoublyLinkedList
, ListItemLinkedWithIndex
>();
151 template <template <typename
> class ListTy
, typename ListItemTy
>
152 static void testSinglyLinkedList() {
154 ListItemTy
*X
= &Items
[0];
155 ListItemTy
*Y
= &Items
[1];
156 ListItemTy
*Z
= &Items
[2];
157 ListItemTy
*A
= &Items
[3];
158 ListItemTy
*B
= &Items
[4];
159 ListItemTy
*C
= &Items
[5];
161 ListTy
<ListItemTy
> L
;
163 L
.init(Items
, sizeof(Items
));
169 EXPECT_EQ(L
.size(), 2U);
170 EXPECT_EQ(L
.front(), X
);
171 EXPECT_EQ(L
.back(), Z
);
172 L
.checkConsistency();
174 EXPECT_EQ(L
.size(), 1U);
175 EXPECT_EQ(L
.front(), X
);
176 EXPECT_EQ(L
.back(), X
);
177 L
.checkConsistency();
179 EXPECT_TRUE(L
.empty());
181 ListTy
<ListItemTy
> L1
, L2
;
184 L1
.init(Items
, sizeof(Items
));
185 L2
.init(Items
, sizeof(Items
));
188 EXPECT_TRUE(L1
.empty());
189 EXPECT_TRUE(L2
.empty());
196 checkList(&L1
, X
, Z
, Y
);
198 setList(&L1
, X
, Y
, Z
);
199 setList(&L2
, A
, B
, C
);
201 checkList(&L1
, X
, Y
, Z
, A
, B
, C
);
202 EXPECT_TRUE(L2
.empty());
208 EXPECT_EQ(L1
.back(), X
);
209 EXPECT_EQ(L1
.front(), X
);
210 EXPECT_EQ(L1
.size(), 1U);
213 TEST(ScudoListTest
, SinglyLinkedList
) {
214 testSinglyLinkedList
<scudo::SinglyLinkedList
, ListItemLinkedWithPtr
>();
215 testSinglyLinkedList
<scudo::SinglyLinkedList
, ListItemLinkedWithIndex
>();
218 template <template <typename
> class ListTy
, typename ListItemTy
>
219 static void testDoublyLinkedList() {
221 ListItemTy
*X
= &Items
[0];
222 ListItemTy
*Y
= &Items
[1];
223 ListItemTy
*Z
= &Items
[2];
225 ListTy
<ListItemTy
> L
;
227 L
.init(Items
, sizeof(Items
));
233 EXPECT_EQ(L
.size(), 2U);
234 EXPECT_EQ(L
.front(), X
);
235 EXPECT_EQ(L
.back(), Z
);
236 L
.checkConsistency();
238 EXPECT_EQ(L
.size(), 1U);
239 EXPECT_EQ(L
.front(), X
);
240 EXPECT_EQ(L
.back(), X
);
241 L
.checkConsistency();
243 EXPECT_TRUE(L
.empty());
247 EXPECT_EQ(L
.size(), 2U);
248 EXPECT_EQ(L
.front(), Y
);
249 EXPECT_EQ(L
.back(), X
);
250 L
.checkConsistency();
252 EXPECT_EQ(L
.size(), 1U);
253 EXPECT_EQ(L
.front(), X
);
254 EXPECT_EQ(L
.back(), X
);
255 L
.checkConsistency();
257 EXPECT_TRUE(L
.empty());
260 TEST(ScudoListTest
, DoublyLinkedList
) {
261 testDoublyLinkedList
<scudo::DoublyLinkedList
, ListItemLinkedWithPtr
>();
262 testDoublyLinkedList
<scudo::DoublyLinkedList
, ListItemLinkedWithIndex
>();