[upstream_utils] Upgrade to LLVM 19.1.6 (#7101)

This commit is contained in:
Tyler Veness
2024-12-24 17:40:31 -08:00
committed by GitHub
parent b670a59b5b
commit 939a9ceee1
70 changed files with 2127 additions and 799 deletions

View File

@@ -0,0 +1,17 @@
//===- llvm/unittest/ADT/CountCopyAndMove.cpp - Optional unit tests -------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "CountCopyAndMove.h"
using namespace wpi;
int CountCopyAndMove::CopyConstructions = 0;
int CountCopyAndMove::CopyAssignments = 0;
int CountCopyAndMove::MoveConstructions = 0;
int CountCopyAndMove::MoveAssignments = 0;
int CountCopyAndMove::Destructions = 0;

View File

@@ -0,0 +1,57 @@
//===- llvm/unittest/ADT/CountCopyAndMove.h - Optional unit tests ---------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_UNITTESTS_ADT_COUNTCOPYANDMOVE_H
#define LLVM_UNITTESTS_ADT_COUNTCOPYANDMOVE_H
namespace wpi {
struct CountCopyAndMove {
static int CopyConstructions;
static int CopyAssignments;
static int MoveConstructions;
static int MoveAssignments;
static int Destructions;
int val;
CountCopyAndMove() = default;
explicit CountCopyAndMove(int val) : val(val) {}
CountCopyAndMove(const CountCopyAndMove &other) : val(other.val) {
++CopyConstructions;
}
CountCopyAndMove &operator=(const CountCopyAndMove &other) {
val = other.val;
++CopyAssignments;
return *this;
}
CountCopyAndMove(CountCopyAndMove &&other) : val(other.val) {
++MoveConstructions;
}
CountCopyAndMove &operator=(CountCopyAndMove &&other) {
val = other.val;
++MoveAssignments;
return *this;
}
~CountCopyAndMove() { ++Destructions; }
static void ResetCounts() {
CopyConstructions = 0;
CopyAssignments = 0;
MoveConstructions = 0;
MoveAssignments = 0;
Destructions = 0;
}
static int TotalCopies() { return CopyConstructions + CopyAssignments; }
static int TotalMoves() { return MoveConstructions + MoveAssignments; }
};
} // end namespace wpi
#endif // LLVM_UNITTESTS_ADT_COUNTCOPYANDMOVE_H

View File

@@ -11,6 +11,7 @@
#endif
#include "wpi/DenseMap.h"
#include "CountCopyAndMove.h"
#include "wpi/DenseMapInfo.h"
#include "wpi/DenseMapInfoVariant.h"
#include "gmock/gmock.h"
@@ -24,7 +25,6 @@
using namespace wpi;
namespace {
uint32_t getTestKey(int i, uint32_t *) { return i; }
uint32_t getTestValue(int i, uint32_t *) { return 42 + i; }
@@ -39,6 +39,14 @@ uint32_t *getTestValue(int i, uint32_t **) {
return &dummy_arr1[i];
}
enum class EnumClass { Val };
EnumClass getTestKey(int i, EnumClass *) {
// We can't possibly support 100 values for the swap test, so just return an
// invalid EnumClass for testing.
return static_cast<EnumClass>(i);
}
/// A test class that tries to check that construction and destruction
/// occur correctly.
class CtorTester {
@@ -107,14 +115,19 @@ template <typename T>
typename T::mapped_type *const DenseMapTest<T>::dummy_value_ptr = nullptr;
// Register these types for testing.
// clang-format off
typedef ::testing::Types<DenseMap<uint32_t, uint32_t>,
DenseMap<uint32_t *, uint32_t *>,
DenseMap<CtorTester, CtorTester, CtorTesterMapInfo>,
DenseMap<EnumClass, uint32_t>,
SmallDenseMap<uint32_t, uint32_t>,
SmallDenseMap<uint32_t *, uint32_t *>,
SmallDenseMap<CtorTester, CtorTester, 4,
CtorTesterMapInfo>
CtorTesterMapInfo>,
SmallDenseMap<EnumClass, uint32_t>
> DenseMapTestTypes;
// clang-format on
TYPED_TEST_SUITE(DenseMapTest, DenseMapTestTypes, );
// Empty map tests
@@ -350,29 +363,6 @@ TYPED_TEST(DenseMapTest, ConstIteratorTest) {
EXPECT_TRUE(cit == cit2);
}
namespace {
// Simple class that counts how many moves and copy happens when growing a map
struct CountCopyAndMove {
static int Move;
static int Copy;
CountCopyAndMove() {}
CountCopyAndMove(const CountCopyAndMove &) { Copy++; }
CountCopyAndMove &operator=(const CountCopyAndMove &) {
Copy++;
return *this;
}
CountCopyAndMove(CountCopyAndMove &&) { Move++; }
CountCopyAndMove &operator=(const CountCopyAndMove &&) {
Move++;
return *this;
}
};
int CountCopyAndMove::Copy = 0;
int CountCopyAndMove::Move = 0;
} // anonymous namespace
// Test initializer list construction.
TEST(DenseMapCustomTest, InitializerList) {
DenseMap<int, int> M({{0, 0}, {0, 1}, {1, 2}});
@@ -405,8 +395,8 @@ TEST(DenseMapCustomTest, DefaultMinReservedSizeTest) {
// Will allocate 64 buckets
Map.reserve(1);
unsigned MemorySize = Map.getMemorySize();
CountCopyAndMove::Copy = 0;
CountCopyAndMove::Move = 0;
CountCopyAndMove::ResetCounts();
for (int i = 0; i < ExpectedMaxInitialEntries; ++i)
Map.insert(std::pair<int, CountCopyAndMove>(std::piecewise_construct,
std::forward_as_tuple(i),
@@ -414,9 +404,9 @@ TEST(DenseMapCustomTest, DefaultMinReservedSizeTest) {
// Check that we didn't grow
EXPECT_EQ(MemorySize, Map.getMemorySize());
// Check that move was called the expected number of times
EXPECT_EQ(ExpectedMaxInitialEntries, CountCopyAndMove::Move);
EXPECT_EQ(ExpectedMaxInitialEntries, CountCopyAndMove::TotalMoves());
// Check that no copy occurred
EXPECT_EQ(0, CountCopyAndMove::Copy);
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
// Adding one extra element should grow the map
Map.insert(std::pair<int, CountCopyAndMove>(
@@ -429,7 +419,7 @@ TEST(DenseMapCustomTest, DefaultMinReservedSizeTest) {
// This relies on move-construction elision, and cannot be reliably tested.
// EXPECT_EQ(ExpectedMaxInitialEntries + 2, CountCopyAndMove::Move);
// Check that no copy occurred
EXPECT_EQ(0, CountCopyAndMove::Copy);
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
}
// Make sure creating the map with an initial size of N actually gives us enough
@@ -443,8 +433,8 @@ TEST(DenseMapCustomTest, InitialSizeTest) {
for (auto Size : {1, 2, 48, 66}) {
DenseMap<int, CountCopyAndMove> Map(Size);
unsigned MemorySize = Map.getMemorySize();
CountCopyAndMove::Copy = 0;
CountCopyAndMove::Move = 0;
CountCopyAndMove::ResetCounts();
for (int i = 0; i < Size; ++i)
Map.insert(std::pair<int, CountCopyAndMove>(std::piecewise_construct,
std::forward_as_tuple(i),
@@ -452,9 +442,9 @@ TEST(DenseMapCustomTest, InitialSizeTest) {
// Check that we didn't grow
EXPECT_EQ(MemorySize, Map.getMemorySize());
// Check that move was called the expected number of times
EXPECT_EQ(Size, CountCopyAndMove::Move);
EXPECT_EQ(Size, CountCopyAndMove::TotalMoves());
// Check that no copy occurred
EXPECT_EQ(0, CountCopyAndMove::Copy);
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
}
}
@@ -465,15 +455,14 @@ TEST(DenseMapCustomTest, InitFromIterator) {
const int Count = 65;
Values.reserve(Count);
for (int i = 0; i < Count; i++)
Values.emplace_back(i, CountCopyAndMove());
Values.emplace_back(i, CountCopyAndMove(i));
CountCopyAndMove::Move = 0;
CountCopyAndMove::Copy = 0;
CountCopyAndMove::ResetCounts();
DenseMap<int, CountCopyAndMove> Map(Values.begin(), Values.end());
// Check that no move occurred
EXPECT_EQ(0, CountCopyAndMove::Move);
EXPECT_EQ(0, CountCopyAndMove::TotalMoves());
// Check that copy was called the expected number of times
EXPECT_EQ(Count, CountCopyAndMove::Copy);
EXPECT_EQ(Count, CountCopyAndMove::TotalCopies());
}
// Make sure reserve actually gives us enough buckets to insert N items
@@ -488,8 +477,7 @@ TEST(DenseMapCustomTest, ReserveTest) {
DenseMap<int, CountCopyAndMove> Map;
Map.reserve(Size);
unsigned MemorySize = Map.getMemorySize();
CountCopyAndMove::Copy = 0;
CountCopyAndMove::Move = 0;
CountCopyAndMove::ResetCounts();
for (int i = 0; i < Size; ++i)
Map.insert(std::pair<int, CountCopyAndMove>(std::piecewise_construct,
std::forward_as_tuple(i),
@@ -497,12 +485,48 @@ TEST(DenseMapCustomTest, ReserveTest) {
// Check that we didn't grow
EXPECT_EQ(MemorySize, Map.getMemorySize());
// Check that move was called the expected number of times
EXPECT_EQ(Size, CountCopyAndMove::Move);
EXPECT_EQ(Size, CountCopyAndMove::TotalMoves());
// Check that no copy occurred
EXPECT_EQ(0, CountCopyAndMove::Copy);
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
}
}
TEST(DenseMapCustomTest, InsertOrAssignTest) {
DenseMap<int, CountCopyAndMove> Map;
CountCopyAndMove val1(1);
CountCopyAndMove::ResetCounts();
auto try0 = Map.insert_or_assign(0, val1);
EXPECT_TRUE(try0.second);
EXPECT_EQ(0, CountCopyAndMove::TotalMoves());
EXPECT_EQ(1, CountCopyAndMove::CopyConstructions);
EXPECT_EQ(0, CountCopyAndMove::CopyAssignments);
CountCopyAndMove::ResetCounts();
auto try1 = Map.insert_or_assign(0, val1);
EXPECT_FALSE(try1.second);
EXPECT_EQ(0, CountCopyAndMove::TotalMoves());
EXPECT_EQ(0, CountCopyAndMove::CopyConstructions);
EXPECT_EQ(1, CountCopyAndMove::CopyAssignments);
int key2 = 2;
CountCopyAndMove val2(2);
CountCopyAndMove::ResetCounts();
auto try2 = Map.insert_or_assign(key2, std::move(val2));
EXPECT_TRUE(try2.second);
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
EXPECT_EQ(1, CountCopyAndMove::MoveConstructions);
EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
CountCopyAndMove val3(3);
CountCopyAndMove::ResetCounts();
auto try3 = Map.insert_or_assign(key2, std::move(val3));
EXPECT_FALSE(try3.second);
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
EXPECT_EQ(1, CountCopyAndMove::MoveAssignments);
}
// Key traits that allows lookup with either an unsigned or char* key;
// In the latter case, "a" == 0, "b" == 1 and so on.
struct TestDenseMapInfo {

View File

@@ -35,6 +35,29 @@ TEST(Endian, Read) {
1)));
}
TEST(Endian, WriteNext) {
unsigned char bigval[] = {0x00, 0x00}, *p = bigval;
endian::writeNext<int16_t, wpi::endianness::big>(p, short(0xaabb));
EXPECT_EQ(bigval[0], 0xaa);
EXPECT_EQ(bigval[1], 0xbb);
EXPECT_EQ(p, bigval + 2);
char littleval[8] = {}, *q = littleval;
endian::writeNext<uint32_t, wpi::endianness::little>(q, 0x44556677);
EXPECT_EQ(littleval[0], 0x77);
EXPECT_EQ(littleval[1], 0x66);
EXPECT_EQ(littleval[2], 0x55);
EXPECT_EQ(littleval[3], 0x44);
EXPECT_EQ(q, littleval + 4);
endian::writeNext<uint32_t>(q, 0x11223344, wpi::endianness::little);
EXPECT_EQ(littleval[4], 0x44);
EXPECT_EQ(littleval[5], 0x33);
EXPECT_EQ(littleval[6], 0x22);
EXPECT_EQ(littleval[7], 0x11);
EXPECT_EQ(q, littleval + 8);
}
TEST(Endian, ReadBitAligned) {
// Simple test to make sure we properly pull out the 0x0 word.
unsigned char littleval[] = {0x3f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff};

View File

@@ -8,6 +8,7 @@
#include "wpi/MathExtras.h"
#include "gtest/gtest.h"
#include <limits>
using namespace wpi;
@@ -41,6 +42,9 @@ TEST(MathExtras, onesMask) {
TEST(MathExtras, isIntN) {
EXPECT_TRUE(isIntN(16, 32767));
EXPECT_FALSE(isIntN(16, 32768));
EXPECT_TRUE(isIntN(0, 0));
EXPECT_FALSE(isIntN(0, 1));
EXPECT_FALSE(isIntN(0, -1));
}
TEST(MathExtras, isUIntN) {
@@ -48,6 +52,8 @@ TEST(MathExtras, isUIntN) {
EXPECT_FALSE(isUIntN(16, 65536));
EXPECT_TRUE(isUIntN(1, 0));
EXPECT_TRUE(isUIntN(6, 63));
EXPECT_TRUE(isUIntN(0, 0));
EXPECT_FALSE(isUIntN(0, 1));
}
TEST(MathExtras, maxIntN) {
@@ -55,6 +61,7 @@ TEST(MathExtras, maxIntN) {
EXPECT_EQ(2147483647, maxIntN(32));
EXPECT_EQ(std::numeric_limits<int32_t>::max(), maxIntN(32));
EXPECT_EQ(std::numeric_limits<int64_t>::max(), maxIntN(64));
EXPECT_EQ(0, maxIntN(0));
}
TEST(MathExtras, minIntN) {
@@ -62,6 +69,7 @@ TEST(MathExtras, minIntN) {
EXPECT_EQ(-64LL, minIntN(7));
EXPECT_EQ(std::numeric_limits<int32_t>::min(), minIntN(32));
EXPECT_EQ(std::numeric_limits<int64_t>::min(), minIntN(64));
EXPECT_EQ(0, minIntN(0));
}
TEST(MathExtras, maxUIntN) {
@@ -70,6 +78,7 @@ TEST(MathExtras, maxUIntN) {
EXPECT_EQ(0xffffffffffffffffULL, maxUIntN(64));
EXPECT_EQ(1ULL, maxUIntN(1));
EXPECT_EQ(0x0fULL, maxUIntN(4));
EXPECT_EQ(0ULL, maxUIntN(0));
}
TEST(MathExtras, reverseBits) {
@@ -167,6 +176,7 @@ TEST(MathExtras, MinAlign) {
EXPECT_EQ(2u, MinAlign(2, 4));
EXPECT_EQ(1u, MinAlign(17, 64));
EXPECT_EQ(256u, MinAlign(256, 512));
EXPECT_EQ(2u, MinAlign(0, 2));
}
TEST(MathExtras, NextPowerOf2) {
@@ -175,15 +185,48 @@ TEST(MathExtras, NextPowerOf2) {
EXPECT_EQ(256u, NextPowerOf2(128));
}
TEST(MathExtras, alignTo) {
TEST(MathExtras, AlignTo) {
EXPECT_EQ(8u, alignTo(5, 8));
EXPECT_EQ(24u, alignTo(17, 8));
EXPECT_EQ(0u, alignTo(~0LL, 8));
EXPECT_EQ(8u, alignTo(5ULL, 8ULL));
EXPECT_EQ(8u, alignTo<8>(5));
EXPECT_EQ(24u, alignTo<8>(17));
EXPECT_EQ(0u, alignTo<8>(~0LL));
EXPECT_EQ(254u,
alignTo<static_cast<uint8_t>(127)>(static_cast<uint8_t>(200)));
EXPECT_EQ(7u, alignTo(5, 8, 7));
EXPECT_EQ(17u, alignTo(17, 8, 1));
EXPECT_EQ(3u, alignTo(~0LL, 8, 3));
EXPECT_EQ(552u, alignTo(321, 255, 42));
EXPECT_EQ(std::numeric_limits<uint32_t>::max(),
alignTo(std::numeric_limits<uint32_t>::max(), 2, 1));
// Overflow.
EXPECT_EQ(0u, alignTo(static_cast<uint8_t>(200), static_cast<uint8_t>(128)));
EXPECT_EQ(0u, alignTo<static_cast<uint8_t>(128)>(static_cast<uint8_t>(200)));
EXPECT_EQ(0u, alignTo(static_cast<uint8_t>(200), static_cast<uint8_t>(128),
static_cast<uint8_t>(0)));
EXPECT_EQ(0u, alignTo(std::numeric_limits<uint32_t>::max(), 2));
}
TEST(MathExtras, AlignToPowerOf2) {
EXPECT_EQ(0u, alignToPowerOf2(0u, 8));
EXPECT_EQ(8u, alignToPowerOf2(5, 8));
EXPECT_EQ(24u, alignToPowerOf2(17, 8));
EXPECT_EQ(0u, alignToPowerOf2(~0LL, 8));
EXPECT_EQ(240u, alignToPowerOf2(240, 16));
EXPECT_EQ(static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()) + 1,
alignToPowerOf2(std::numeric_limits<uint32_t>::max(), 2));
}
TEST(MathExtras, AlignDown) {
EXPECT_EQ(0u, alignDown(5, 8));
EXPECT_EQ(16u, alignDown(17, 8));
EXPECT_EQ(std::numeric_limits<uint32_t>::max() - 1,
alignDown(std::numeric_limits<uint32_t>::max(), 2));
}
template <typename T> void SaturatingAddTestHelper() {
@@ -426,8 +469,102 @@ TEST(MathExtras, IsShiftedInt) {
EXPECT_FALSE((isShiftedInt<6, 10>(int64_t(1) << 15)));
}
template <typename T>
class OverflowTest : public ::testing::Test { };
TEST(MathExtras, DivideNearest) {
EXPECT_EQ(divideNearest(14, 3), 5u);
EXPECT_EQ(divideNearest(15, 3), 5u);
EXPECT_EQ(divideNearest(0, 3), 0u);
EXPECT_EQ(divideNearest(5, 4), 1u);
EXPECT_EQ(divideNearest(6, 4), 2u);
EXPECT_EQ(divideNearest(3, 1), 3u);
EXPECT_EQ(divideNearest(3, 6), 1u);
EXPECT_EQ(divideNearest(3, 7), 0u);
EXPECT_EQ(divideNearest(std::numeric_limits<uint32_t>::max(), 2),
std::numeric_limits<uint32_t>::max() / 2 + 1);
EXPECT_EQ(divideNearest(std::numeric_limits<uint64_t>::max(), 2),
std::numeric_limits<uint64_t>::max() / 2 + 1);
EXPECT_EQ(divideNearest(std::numeric_limits<uint64_t>::max(), 1),
std::numeric_limits<uint64_t>::max());
EXPECT_EQ(divideNearest(std::numeric_limits<uint64_t>::max() - 1,
std::numeric_limits<uint64_t>::max()),
1u);
}
TEST(MathExtras, DivideCeil) {
EXPECT_EQ(divideCeil(14, 3), 5u);
EXPECT_EQ(divideCeil(15, 3), 5u);
EXPECT_EQ(divideCeil(0, 3), 0u);
EXPECT_EQ(divideCeil(5, 4), 2u);
EXPECT_EQ(divideCeil(6, 4), 2u);
EXPECT_EQ(divideCeil(3, 1), 3u);
EXPECT_EQ(divideCeil(3, 6), 1u);
EXPECT_EQ(divideCeil(3, 7), 1u);
EXPECT_EQ(divideCeil(std::numeric_limits<uint32_t>::max(), 2),
std::numeric_limits<uint32_t>::max() / 2 + 1);
EXPECT_EQ(divideCeil(std::numeric_limits<uint64_t>::max(), 2),
std::numeric_limits<uint64_t>::max() / 2 + 1);
EXPECT_EQ(divideCeil(std::numeric_limits<uint64_t>::max(), 1),
std::numeric_limits<uint64_t>::max());
EXPECT_EQ(divideCeilSigned(14, 3), 5);
EXPECT_EQ(divideCeilSigned(15, 3), 5);
EXPECT_EQ(divideCeilSigned(14, -3), -4);
EXPECT_EQ(divideCeilSigned(-14, -3), 5);
EXPECT_EQ(divideCeilSigned(-14, 3), -4);
EXPECT_EQ(divideCeilSigned(-15, 3), -5);
EXPECT_EQ(divideCeilSigned(0, 3), 0);
EXPECT_EQ(divideCeilSigned(0, -3), 0);
EXPECT_EQ(divideCeilSigned(std::numeric_limits<int32_t>::max(), 2),
std::numeric_limits<int32_t>::max() / 2 + 1);
EXPECT_EQ(divideCeilSigned(std::numeric_limits<int64_t>::max(), 2),
std::numeric_limits<int64_t>::max() / 2 + 1);
EXPECT_EQ(divideCeilSigned(std::numeric_limits<int32_t>::max(), -2),
std::numeric_limits<int32_t>::min() / 2 + 1);
EXPECT_EQ(divideCeilSigned(std::numeric_limits<int64_t>::max(), -2),
std::numeric_limits<int64_t>::min() / 2 + 1);
EXPECT_EQ(divideCeilSigned(std::numeric_limits<int64_t>::min(), 1),
std::numeric_limits<int64_t>::min());
// Overflow.
EXPECT_TRUE(
divideSignedWouldOverflow(std::numeric_limits<int8_t>::min(), -1));
EXPECT_TRUE(
divideSignedWouldOverflow(std::numeric_limits<int64_t>::min(), -1));
}
TEST(MathExtras, DivideFloorSigned) {
EXPECT_EQ(divideFloorSigned(14, 3), 4);
EXPECT_EQ(divideFloorSigned(15, 3), 5);
EXPECT_EQ(divideFloorSigned(14, -3), -5);
EXPECT_EQ(divideFloorSigned(-14, -3), 4);
EXPECT_EQ(divideFloorSigned(-14, 3), -5);
EXPECT_EQ(divideFloorSigned(-15, 3), -5);
EXPECT_EQ(divideFloorSigned(0, 3), 0);
EXPECT_EQ(divideFloorSigned(0, -3), 0);
EXPECT_EQ(divideFloorSigned(std::numeric_limits<int32_t>::max(), 2),
std::numeric_limits<int32_t>::max() / 2);
EXPECT_EQ(divideFloorSigned(std::numeric_limits<int64_t>::max(), 2),
std::numeric_limits<int64_t>::max() / 2);
EXPECT_EQ(divideFloorSigned(std::numeric_limits<int32_t>::max(), -2),
std::numeric_limits<int32_t>::min() / 2);
EXPECT_EQ(divideFloorSigned(std::numeric_limits<int64_t>::max(), -2),
std::numeric_limits<int64_t>::min() / 2);
EXPECT_EQ(divideFloorSigned(std::numeric_limits<int64_t>::min(), 1),
std::numeric_limits<int64_t>::min());
// Same overflow condition, divideSignedWouldOverflow, applies.
}
TEST(MathExtras, Mod) {
EXPECT_EQ(mod(1, 14), 1);
EXPECT_EQ(mod(-1, 14), 13);
EXPECT_EQ(mod(14, 3), 2);
EXPECT_EQ(mod(15, 3), 0);
EXPECT_EQ(mod(-14, 3), 1);
EXPECT_EQ(mod(-15, 3), 0);
EXPECT_EQ(mod(0, 3), 0);
}
template <typename T> class OverflowTest : public ::testing::Test {};
using OverflowTestTypes = ::testing::Types<signed char, short, int, long,
long long>;
@@ -552,5 +689,4 @@ TYPED_TEST(OverflowTest, MulResultZero) {
EXPECT_FALSE(MulOverflow<TypeParam>(0, -5, Result));
EXPECT_EQ(Result, TypeParam(0));
}
} // namespace

View File

@@ -1,15 +0,0 @@
//===- llvm/unittest/ADT/MoveOnly.cpp - Optional unit tests ---------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "MoveOnly.h"
using namespace wpi;
unsigned MoveOnly::MoveConstructions = 0;
unsigned MoveOnly::Destructions = 0;
unsigned MoveOnly::MoveAssignments = 0;

View File

@@ -1,42 +0,0 @@
//===- llvm/unittest/ADT/MoveOnly.h - Optional unit tests -----------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_UNITTESTS_ADT_MOVEONLY_H
#define LLVM_UNITTESTS_ADT_MOVEONLY_H
namespace wpi {
struct MoveOnly {
static unsigned MoveConstructions;
static unsigned Destructions;
static unsigned MoveAssignments;
int val;
explicit MoveOnly(int val) : val(val) {
}
MoveOnly(MoveOnly&& other) {
val = other.val;
++MoveConstructions;
}
MoveOnly &operator=(MoveOnly&& other) {
val = other.val;
++MoveAssignments;
return *this;
}
~MoveOnly() {
++Destructions;
}
static void ResetCounts() {
MoveConstructions = 0;
Destructions = 0;
MoveAssignments = 0;
}
};
} // end namespace wpi
#endif // LLVM_UNITTESTS_ADT_MOVEONLY_H

View File

@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "wpi/STLForwardCompat.h"
#include "MoveOnly.h"
#include "CountCopyAndMove.h"
#include "gtest/gtest.h"
namespace {
@@ -58,27 +58,29 @@ TEST(TransformTest, TransformStd) {
}
TEST(TransformTest, MoveTransformStd) {
using wpi::MoveOnly;
using wpi::CountCopyAndMove;
std::optional<MoveOnly> A;
std::optional<CountCopyAndMove> A;
MoveOnly::ResetCounts();
CountCopyAndMove::ResetCounts();
std::optional<int> B = wpi::transformOptional(
std::move(A), [&](const MoveOnly &M) { return M.val + 2; });
std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
EXPECT_FALSE(B.has_value());
EXPECT_EQ(0u, MoveOnly::MoveConstructions);
EXPECT_EQ(0u, MoveOnly::MoveAssignments);
EXPECT_EQ(0u, MoveOnly::Destructions);
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
EXPECT_EQ(0, CountCopyAndMove::Destructions);
A = MoveOnly(5);
MoveOnly::ResetCounts();
A = CountCopyAndMove(5);
CountCopyAndMove::ResetCounts();
std::optional<int> C = wpi::transformOptional(
std::move(A), [&](const MoveOnly &M) { return M.val + 2; });
std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
EXPECT_TRUE(C.has_value());
EXPECT_EQ(7, *C);
EXPECT_EQ(0u, MoveOnly::MoveConstructions);
EXPECT_EQ(0u, MoveOnly::MoveAssignments);
EXPECT_EQ(0u, MoveOnly::Destructions);
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
EXPECT_EQ(0, CountCopyAndMove::Destructions);
}
TEST(TransformTest, TransformLlvm) {
@@ -96,27 +98,29 @@ TEST(TransformTest, TransformLlvm) {
}
TEST(TransformTest, MoveTransformLlvm) {
using wpi::MoveOnly;
using wpi::CountCopyAndMove;
std::optional<MoveOnly> A;
std::optional<CountCopyAndMove> A;
MoveOnly::ResetCounts();
CountCopyAndMove::ResetCounts();
std::optional<int> B = wpi::transformOptional(
std::move(A), [&](const MoveOnly &M) { return M.val + 2; });
std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
EXPECT_FALSE(B.has_value());
EXPECT_EQ(0u, MoveOnly::MoveConstructions);
EXPECT_EQ(0u, MoveOnly::MoveAssignments);
EXPECT_EQ(0u, MoveOnly::Destructions);
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
EXPECT_EQ(0, CountCopyAndMove::Destructions);
A = MoveOnly(5);
MoveOnly::ResetCounts();
A = CountCopyAndMove(5);
CountCopyAndMove::ResetCounts();
std::optional<int> C = wpi::transformOptional(
std::move(A), [&](const MoveOnly &M) { return M.val + 2; });
std::move(A), [&](const CountCopyAndMove &M) { return M.val + 2; });
EXPECT_TRUE(C.has_value());
EXPECT_EQ(7, *C);
EXPECT_EQ(0u, MoveOnly::MoveConstructions);
EXPECT_EQ(0u, MoveOnly::MoveAssignments);
EXPECT_EQ(0u, MoveOnly::Destructions);
EXPECT_EQ(0, CountCopyAndMove::TotalCopies());
EXPECT_EQ(0, CountCopyAndMove::MoveConstructions);
EXPECT_EQ(0, CountCopyAndMove::MoveAssignments);
EXPECT_EQ(0, CountCopyAndMove::Destructions);
}
TEST(TransformTest, ToUnderlying) {

View File

@@ -244,45 +244,6 @@ TEST(SmallPtrSetTest, SwapTest) {
EXPECT_TRUE(a.count(&buf[3]));
}
void checkEraseAndIterators(SmallPtrSetImpl<int*> &S) {
int buf[3];
S.insert(&buf[0]);
S.insert(&buf[1]);
S.insert(&buf[2]);
// Iterators must still be valid after erase() calls;
auto B = S.begin();
auto M = std::next(B);
auto E = S.end();
EXPECT_TRUE(*B == &buf[0] || *B == &buf[1] || *B == &buf[2]);
EXPECT_TRUE(*M == &buf[0] || *M == &buf[1] || *M == &buf[2]);
EXPECT_TRUE(*B != *M);
int *Removable = *std::next(M);
// No iterator points to Removable now.
EXPECT_TRUE(Removable == &buf[0] || Removable == &buf[1] ||
Removable == &buf[2]);
EXPECT_TRUE(Removable != *B && Removable != *M);
S.erase(Removable);
// B,M,E iterators should still be valid
EXPECT_EQ(B, S.begin());
EXPECT_EQ(M, std::next(B));
EXPECT_EQ(E, S.end());
EXPECT_EQ(std::next(M), E);
}
TEST(SmallPtrSetTest, EraseTest) {
// Test when set stays small.
SmallPtrSet<int *, 8> B;
checkEraseAndIterators(B);
// Test when set grows big.
SmallPtrSet<int *, 2> A;
checkEraseAndIterators(A);
}
// Verify that dereferencing and iteration work.
TEST(SmallPtrSetTest, dereferenceAndIterate) {
int Ints[] = {0, 1, 2, 3, 4, 5, 6, 7};
@@ -410,3 +371,41 @@ TEST(SmallPtrSetTest, InsertIterator) {
for (const auto *Ptr : Buf)
EXPECT_TRUE(Set.contains(Ptr));
}
TEST(SmallPtrSetTest, RemoveIf) {
SmallPtrSet<int *, 5> Set;
int Vals[6] = {0, 1, 2, 3, 4, 5};
// Stay in small regime.
Set.insert(&Vals[0]);
Set.insert(&Vals[1]);
Set.insert(&Vals[2]);
Set.insert(&Vals[3]);
Set.erase(&Vals[0]); // Leave a tombstone.
// Remove odd elements.
bool Removed = Set.remove_if([](int *Ptr) { return *Ptr % 2 != 0; });
// We should only have element 2 left now.
EXPECT_TRUE(Removed);
EXPECT_EQ(Set.size(), 1u);
EXPECT_TRUE(Set.contains(&Vals[2]));
// Switch to big regime.
Set.insert(&Vals[0]);
Set.insert(&Vals[1]);
Set.insert(&Vals[3]);
Set.insert(&Vals[4]);
Set.insert(&Vals[5]);
Set.erase(&Vals[0]); // Leave a tombstone.
// Remove odd elements.
Removed = Set.remove_if([](int *Ptr) { return *Ptr % 2 != 0; });
// We should only have elements 2 and 4 left now.
EXPECT_TRUE(Removed);
EXPECT_EQ(Set.size(), 2u);
EXPECT_TRUE(Set.contains(&Vals[2]));
EXPECT_TRUE(Set.contains(&Vals[4]));
Removed = Set.remove_if([](int *Ptr) { return false; });
EXPECT_FALSE(Removed);
}

View File

@@ -11,6 +11,26 @@
using namespace wpi;
/* use #define to make them constant, required for initialization */
#define PRIME32 2654435761U
#define PRIME64 11400714785074694797ULL
/*
* Fills a test buffer with pseudorandom data.
*
* This is used in the sanity check - its values must not be changed.
*/
static void fillTestBuffer(uint8_t *buffer, size_t len) {
uint64_t byteGen = PRIME32;
assert(buffer != NULL);
for (size_t i = 0; i < len; i++) {
buffer[i] = (uint8_t)(byteGen >> 56);
byteGen *= PRIME64;
}
}
TEST(xxhashTest, Basic) {
EXPECT_EQ(0xef46db3751d8e999U, xxHash64(std::string_view()));
EXPECT_EQ(0x33bf00a859c4ba3fU, xxHash64("foo"));
@@ -61,3 +81,52 @@ TEST(xxhashTest, xxh3) {
F(2243, 0x0979f786a24edde7);
#undef F
}
TEST(xxhashTest, xxh3_128bits) {
#define SANITY_BUFFER_SIZE 2367
uint8_t sanityBuffer[SANITY_BUFFER_SIZE];
fillTestBuffer(sanityBuffer, sizeof(sanityBuffer));
#define F(len, expected) \
EXPECT_EQ(XXH128_hash_t(expected), \
xxh3_128bits(std::span(sanityBuffer, size_t(len))))
F(0, (XXH128_hash_t{0x6001C324468D497FULL,
0x99AA06D3014798D8ULL})); /* empty string */
F(1, (XXH128_hash_t{0xC44BDFF4074EECDBULL,
0xA6CD5E9392000F6AULL})); /* 1 - 3 */
F(6, (XXH128_hash_t{0x3E7039BDDA43CFC6ULL,
0x082AFE0B8162D12AULL})); /* 4 - 8 */
F(12, (XXH128_hash_t{0x061A192713F69AD9ULL,
0x6E3EFD8FC7802B18ULL})); /* 9 - 16 */
F(24, (XXH128_hash_t{0x1E7044D28B1B901DULL,
0x0CE966E4678D3761ULL})); /* 17 - 32 */
F(48, (XXH128_hash_t{0xF942219AED80F67BULL,
0xA002AC4E5478227EULL})); /* 33 - 64 */
F(81, (XXH128_hash_t{0x5E8BAFB9F95FB803ULL,
0x4952F58181AB0042ULL})); /* 65 - 96 */
F(222, (XXH128_hash_t{0xF1AEBD597CEC6B3AULL,
0x337E09641B948717ULL})); /* 129-240 */
F(403,
(XXH128_hash_t{
0xCDEB804D65C6DEA4ULL,
0x1B6DE21E332DD73DULL})); /* one block, last stripe is overlapping */
F(512,
(XXH128_hash_t{
0x617E49599013CB6BULL,
0x18D2D110DCC9BCA1ULL})); /* one block, finishing at stripe boundary */
F(2048,
(XXH128_hash_t{
0xDD59E2C3A5F038E0ULL,
0xF736557FD47073A5ULL})); /* 2 blocks, finishing at block boundary */
F(2240,
(XXH128_hash_t{
0x6E73A90539CF2948ULL,
0xCCB134FBFA7CE49DULL})); /* 3 blocks, finishing at stripe boundary */
F(2367,
(XXH128_hash_t{
0xCB37AEB9E5D361EDULL,
0xE89C0F6FF369B427ULL})); /* 3 blocks, last stripe is overlapping */
#undef F
}