| //===-- sanitizer_list_test.cpp -------------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file is a part of ThreadSanitizer/AddressSanitizer runtime. |
| // |
| //===----------------------------------------------------------------------===// |
| #include "sanitizer_common/sanitizer_list.h" |
| #include "gtest/gtest.h" |
| |
| namespace __sanitizer { |
| |
| struct ListItem { |
| ListItem *next; |
| }; |
| |
| typedef IntrusiveList<ListItem> List; |
| |
| static List static_list; |
| |
| static void SetList(List *l, ListItem *x = 0, |
| ListItem *y = 0, ListItem *z = 0) { |
| l->clear(); |
| if (x) l->push_back(x); |
| if (y) l->push_back(y); |
| if (z) l->push_back(z); |
| } |
| |
| static void CheckList(List *l, ListItem *i1, ListItem *i2 = 0, ListItem *i3 = 0, |
| ListItem *i4 = 0, ListItem *i5 = 0, ListItem *i6 = 0) { |
| if (i1) { |
| CHECK_EQ(l->front(), i1); |
| l->pop_front(); |
| } |
| if (i2) { |
| CHECK_EQ(l->front(), i2); |
| l->pop_front(); |
| } |
| if (i3) { |
| CHECK_EQ(l->front(), i3); |
| l->pop_front(); |
| } |
| if (i4) { |
| CHECK_EQ(l->front(), i4); |
| l->pop_front(); |
| } |
| if (i5) { |
| CHECK_EQ(l->front(), i5); |
| l->pop_front(); |
| } |
| if (i6) { |
| CHECK_EQ(l->front(), i6); |
| l->pop_front(); |
| } |
| CHECK(l->empty()); |
| } |
| |
| TEST(SanitizerCommon, IntrusiveList) { |
| ListItem items[6]; |
| CHECK_EQ(static_list.size(), 0); |
| |
| List l; |
| l.clear(); |
| |
| ListItem *x = &items[0]; |
| ListItem *y = &items[1]; |
| ListItem *z = &items[2]; |
| ListItem *a = &items[3]; |
| ListItem *b = &items[4]; |
| ListItem *c = &items[5]; |
| |
| CHECK_EQ(l.size(), 0); |
| l.push_back(x); |
| CHECK_EQ(l.size(), 1); |
| CHECK_EQ(l.back(), x); |
| CHECK_EQ(l.front(), x); |
| l.pop_front(); |
| CHECK(l.empty()); |
| l.CheckConsistency(); |
| |
| l.push_front(x); |
| CHECK_EQ(l.size(), 1); |
| CHECK_EQ(l.back(), x); |
| CHECK_EQ(l.front(), x); |
| l.pop_front(); |
| CHECK(l.empty()); |
| l.CheckConsistency(); |
| |
| l.push_front(x); |
| l.push_front(y); |
| l.push_front(z); |
| CHECK_EQ(l.size(), 3); |
| CHECK_EQ(l.front(), z); |
| CHECK_EQ(l.back(), x); |
| l.CheckConsistency(); |
| |
| l.pop_front(); |
| CHECK_EQ(l.size(), 2); |
| CHECK_EQ(l.front(), y); |
| CHECK_EQ(l.back(), x); |
| l.pop_front(); |
| l.pop_front(); |
| CHECK(l.empty()); |
| l.CheckConsistency(); |
| |
| l.push_back(x); |
| l.push_back(y); |
| l.push_back(z); |
| CHECK_EQ(l.size(), 3); |
| CHECK_EQ(l.front(), x); |
| CHECK_EQ(l.back(), z); |
| l.CheckConsistency(); |
| |
| l.pop_front(); |
| CHECK_EQ(l.size(), 2); |
| CHECK_EQ(l.front(), y); |
| CHECK_EQ(l.back(), z); |
| l.pop_front(); |
| l.pop_front(); |
| CHECK(l.empty()); |
| l.CheckConsistency(); |
| |
| l.push_back(x); |
| l.push_back(y); |
| l.push_back(z); |
| l.extract(x, y); |
| CHECK_EQ(l.size(), 2); |
| CHECK_EQ(l.front(), x); |
| CHECK_EQ(l.back(), z); |
| l.CheckConsistency(); |
| l.extract(x, z); |
| CHECK_EQ(l.size(), 1); |
| CHECK_EQ(l.front(), x); |
| CHECK_EQ(l.back(), x); |
| l.CheckConsistency(); |
| l.pop_front(); |
| CHECK(l.empty()); |
| |
| List l1, l2; |
| l1.clear(); |
| l2.clear(); |
| |
| l1.append_front(&l2); |
| CHECK(l1.empty()); |
| CHECK(l2.empty()); |
| |
| l1.append_back(&l2); |
| CHECK(l1.empty()); |
| CHECK(l2.empty()); |
| |
| SetList(&l1, x); |
| CheckList(&l1, x); |
| |
| SetList(&l1, x, y, z); |
| SetList(&l2, a, b, c); |
| l1.append_back(&l2); |
| CheckList(&l1, x, y, z, a, b, c); |
| CHECK(l2.empty()); |
| |
| SetList(&l1, x, y); |
| SetList(&l2); |
| l1.append_front(&l2); |
| CheckList(&l1, x, y); |
| CHECK(l2.empty()); |
| } |
| |
| TEST(SanitizerCommon, IntrusiveListAppendEmpty) { |
| ListItem i; |
| List l; |
| l.clear(); |
| l.push_back(&i); |
| List l2; |
| l2.clear(); |
| l.append_back(&l2); |
| CHECK_EQ(l.back(), &i); |
| CHECK_EQ(l.front(), &i); |
| CHECK_EQ(l.size(), 1); |
| l.append_front(&l2); |
| CHECK_EQ(l.back(), &i); |
| CHECK_EQ(l.front(), &i); |
| CHECK_EQ(l.size(), 1); |
| } |
| |
| } // namespace __sanitizer |