aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/Support
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests/Support')
-rw-r--r--llvm/unittests/Support/AlignOfTest.cpp16
-rw-r--r--llvm/unittests/Support/AllocatorTest.cpp2
-rw-r--r--llvm/unittests/Support/BinaryStreamTest.cpp2
-rw-r--r--llvm/unittests/Support/Casting.cpp51
-rw-r--r--llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp2
-rw-r--r--llvm/unittests/Support/DynamicLibrary/PipSqueak.h2
-rw-r--r--llvm/unittests/Support/HashBuilderTest.cpp1
-rw-r--r--llvm/unittests/Support/InstructionCostTest.cpp2
-rw-r--r--llvm/unittests/Support/JobserverTest.cpp81
-rw-r--r--llvm/unittests/Support/LockFileManagerTest.cpp1
-rw-r--r--llvm/unittests/Support/ModRefTest.cpp2
-rw-r--r--llvm/unittests/Support/NativeFormatTests.cpp2
-rw-r--r--llvm/unittests/Support/OptimizedStructLayoutTest.cpp2
-rw-r--r--llvm/unittests/Support/ParallelTest.cpp1
-rw-r--r--llvm/unittests/Support/Path.cpp4
-rw-r--r--llvm/unittests/Support/SignalsTest.cpp6
-rw-r--r--llvm/unittests/Support/SpecialCaseListTest.cpp32
-rw-r--r--llvm/unittests/Support/ThreadPool.cpp51
-rw-r--r--llvm/unittests/Support/YAMLIOTest.cpp4
-rw-r--r--llvm/unittests/Support/raw_ostream_proxy_test.cpp2
20 files changed, 206 insertions, 60 deletions
diff --git a/llvm/unittests/Support/AlignOfTest.cpp b/llvm/unittests/Support/AlignOfTest.cpp
index 979f2cf..53358a28 100644
--- a/llvm/unittests/Support/AlignOfTest.cpp
+++ b/llvm/unittests/Support/AlignOfTest.cpp
@@ -79,14 +79,14 @@ struct V8 : V5, virtual V6, V7 { double zz;
double S6::f() { return 0.0; }
float D2::g() { return 0.0f; }
-V1::~V1() {}
-V2::~V2() {}
-V3::~V3() {}
-V4::~V4() {}
-V5::~V5() {}
-V6::~V6() {}
-V7::~V7() {}
-V8::~V8() {}
+V1::~V1() = default;
+V2::~V2() = default;
+V3::~V3() = default;
+V4::~V4() = default;
+V5::~V5() = default;
+V6::~V6() = default;
+V7::~V7() = default;
+V8::~V8() = default;
template <typename M> struct T { M m; };
diff --git a/llvm/unittests/Support/AllocatorTest.cpp b/llvm/unittests/Support/AllocatorTest.cpp
index 1069e43..2337f34 100644
--- a/llvm/unittests/Support/AllocatorTest.cpp
+++ b/llvm/unittests/Support/AllocatorTest.cpp
@@ -235,7 +235,7 @@ class MockSlabAllocator {
static size_t LastSlabSize;
public:
- ~MockSlabAllocator() { }
+ ~MockSlabAllocator() = default;
void *Allocate(size_t Size, size_t /*Alignment*/) {
// Allocate space for the alignment, the slab, and a void* that goes right
diff --git a/llvm/unittests/Support/BinaryStreamTest.cpp b/llvm/unittests/Support/BinaryStreamTest.cpp
index 70cd403..06ed12b 100644
--- a/llvm/unittests/Support/BinaryStreamTest.cpp
+++ b/llvm/unittests/Support/BinaryStreamTest.cpp
@@ -110,7 +110,7 @@ constexpr uint32_t NumStreams = 2 * NumEndians;
class BinaryStreamTest : public testing::Test {
public:
- BinaryStreamTest() {}
+ BinaryStreamTest() = default;
void SetUp() override {
Streams.clear();
diff --git a/llvm/unittests/Support/Casting.cpp b/llvm/unittests/Support/Casting.cpp
index 18327f6..0df8b9f 100644
--- a/llvm/unittests/Support/Casting.cpp
+++ b/llvm/unittests/Support/Casting.cpp
@@ -23,7 +23,7 @@ template <typename T> IllegalCast *cast(...) { return nullptr; }
// with conversion facility
//
struct bar {
- bar() {}
+ bar() = default;
bar(const bar &) = delete;
struct foo *baz();
struct foo *caz();
@@ -36,7 +36,7 @@ struct foo {
};
struct base {
- virtual ~base() {}
+ virtual ~base() = default;
};
struct derived : public base {
@@ -375,12 +375,12 @@ namespace inferred_upcasting {
class Base {
public:
// No classof. We are testing that the upcast is inferred.
- Base() {}
+ Base() = default;
};
class Derived : public Base {
public:
- Derived() {}
+ Derived() = default;
};
// Even with no explicit classof() in Base, we should still be able to cast
@@ -529,7 +529,7 @@ TEST(CastingTest, smart_dyn_cast_or_null) {
#ifndef NDEBUG
namespace assertion_checks {
struct Base {
- virtual ~Base() {}
+ virtual ~Base() = default;
};
struct Derived : public Base {
@@ -561,6 +561,47 @@ TEST(CastingTest, assertion_check_unique_ptr) {
<< "Invalid cast of const ref did not cause an abort()";
}
+TEST(Casting, StaticCastPredicate) {
+ uint32_t Value = 1;
+
+ static_assert(
+ std::is_same_v<decltype(StaticCastTo<uint64_t>(Value)), uint64_t>);
+}
+
+TEST(Casting, LLVMRTTIPredicates) {
+ struct Base {
+ enum Kind { BK_Base, BK_Derived };
+ const Kind K;
+ Base(Kind K = BK_Base) : K(K) {}
+ Kind getKind() const { return K; }
+ virtual ~Base() = default;
+ };
+
+ struct Derived : Base {
+ Derived() : Base(BK_Derived) {}
+ static bool classof(const Base *B) { return B->getKind() == BK_Derived; }
+ bool Field = false;
+ };
+
+ Base B;
+ Derived D;
+ Base *BD = &D;
+ Base *Null = nullptr;
+
+ // Pointers.
+ EXPECT_EQ(DynCastTo<Derived>(BD), &D);
+ EXPECT_EQ(CastTo<Derived>(BD), &D);
+ EXPECT_EQ(DynCastTo<Derived>(&B), nullptr);
+ EXPECT_EQ(CastIfPresentTo<Derived>(BD), &D);
+ EXPECT_EQ(CastIfPresentTo<Derived>(Null), nullptr);
+ EXPECT_EQ(DynCastIfPresentTo<Derived>(BD), &D);
+ EXPECT_EQ(DynCastIfPresentTo<Derived>(Null), nullptr);
+
+ Base &R = D;
+ CastTo<Derived>(R).Field = true;
+ EXPECT_TRUE(D.Field);
+}
+
} // end namespace assertion_checks
#endif
} // end namespace
diff --git a/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp b/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp
index 8ff2c30..8f115ae 100644
--- a/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp
+++ b/llvm/unittests/Support/DynamicLibrary/PipSqueak.cpp
@@ -8,6 +8,8 @@
#include "PipSqueak.h"
+#include <vector>
+
struct Global {
std::string *Str;
std::vector<std::string> *Vec;
diff --git a/llvm/unittests/Support/DynamicLibrary/PipSqueak.h b/llvm/unittests/Support/DynamicLibrary/PipSqueak.h
index dc069ca..f69c7bfa 100644
--- a/llvm/unittests/Support/DynamicLibrary/PipSqueak.h
+++ b/llvm/unittests/Support/DynamicLibrary/PipSqueak.h
@@ -15,11 +15,9 @@
#pragma warning(disable: 4530)
#pragma warning(disable: 4577)
#include <string>
-#include <vector>
#pragma warning(pop)
#else
#include <string>
-#include <vector>
#endif
#if defined(_WIN32) || defined(__CYGWIN__)
diff --git a/llvm/unittests/Support/HashBuilderTest.cpp b/llvm/unittests/Support/HashBuilderTest.cpp
index 0aacfcd..70cb92b 100644
--- a/llvm/unittests/Support/HashBuilderTest.cpp
+++ b/llvm/unittests/Support/HashBuilderTest.cpp
@@ -15,7 +15,6 @@
#include <list>
#include <string>
-#include <type_traits>
#include <utility>
#include <vector>
diff --git a/llvm/unittests/Support/InstructionCostTest.cpp b/llvm/unittests/Support/InstructionCostTest.cpp
index efe8388..5392689 100644
--- a/llvm/unittests/Support/InstructionCostTest.cpp
+++ b/llvm/unittests/Support/InstructionCostTest.cpp
@@ -14,7 +14,7 @@ using namespace llvm;
namespace {
struct CostTest : public testing::Test {
- CostTest() {}
+ CostTest() = default;
};
} // namespace
diff --git a/llvm/unittests/Support/JobserverTest.cpp b/llvm/unittests/Support/JobserverTest.cpp
index d274458..df62346 100644
--- a/llvm/unittests/Support/JobserverTest.cpp
+++ b/llvm/unittests/Support/JobserverTest.cpp
@@ -15,6 +15,7 @@
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Parallel.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
@@ -40,6 +41,9 @@
using namespace llvm;
+// Provided by the unit test main to locate the current test binary.
+extern const char *TestMainArgv0;
+
namespace {
// RAII helper to set an environment variable for the duration of a test.
@@ -218,6 +222,9 @@ TEST_F(JobserverClientTest, UnixClientFifo) {
}
#if LLVM_ENABLE_THREADS
+// Unique anchor whose address helps locate the current test binary.
+static int JobserverTestAnchor = 0;
+
// Test fixture for tests that use the jobserver strategy. It creates a
// temporary FIFO, sets MAKEFLAGS, and provides a helper to pre-load the FIFO
// with job tokens, simulating `make -jN`.
@@ -382,51 +389,93 @@ TEST_F(JobserverStrategyTest, ThreadPoolConcurrencyIsLimited) {
EXPECT_EQ(CompletedTasks, NumTasks);
}
-TEST_F(JobserverStrategyTest, ParallelForIsLimited) {
+// Parent-side driver that spawns a fresh process to run the child test which
+// validates that parallelFor respects the jobserver limit when it is the first
+// user of the default executor in that process.
+TEST_F(JobserverStrategyTest, ParallelForIsLimited_Subprocess) {
+ // Mark child execution.
+ setenv("LLVM_JOBSERVER_TEST_CHILD", "1", 1);
+
+ // Find the current test binary and build args to run only the child test.
+ std::string Executable =
+ sys::fs::getMainExecutable(TestMainArgv0, &JobserverTestAnchor);
+ ASSERT_FALSE(Executable.empty()) << "Failed to get main executable path";
+ SmallVector<StringRef, 4> Args{Executable,
+ "--gtest_filter=JobserverStrategyTest."
+ "ParallelForIsLimited_SubprocessChild"};
+
+ std::string Error;
+ bool ExecFailed = false;
+ int RC = sys::ExecuteAndWait(Executable, Args, std::nullopt, {}, 0, 0, &Error,
+ &ExecFailed);
+ unsetenv("LLVM_JOBSERVER_TEST_CHILD");
+ ASSERT_FALSE(ExecFailed) << Error;
+ ASSERT_EQ(RC, 0) << "Executable failed with exit code " << RC;
+}
+
+// Child-side test: create FIFO and make-proxy in this process, set the
+// jobserver strategy, and then run parallelFor.
+TEST_F(JobserverStrategyTest, ParallelForIsLimited_SubprocessChild) {
+ if (!getenv("LLVM_JOBSERVER_TEST_CHILD"))
+ GTEST_SKIP() << "Not running in child mode";
+
// This test verifies that llvm::parallelFor respects the jobserver limit.
const int NumExplicitJobs = 3;
const int ConcurrencyLimit = NumExplicitJobs + 1; // +1 implicit
const int NumTasks = 20;
- LLVM_DEBUG(dbgs() << "Calling startMakeProxy with " << NumExplicitJobs
- << " jobs.\n");
startMakeProxy(NumExplicitJobs);
- LLVM_DEBUG(dbgs() << "MakeProxy is running.\n");
- // Set the global strategy. parallelFor will use this.
+ // Set the global strategy before any default executor is created.
parallel::strategy = jobserver_concurrency();
std::atomic<int> ActiveTasks{0};
std::atomic<int> MaxActiveTasks{0};
- parallelFor(0, NumTasks, [&](int i) {
+ parallelFor(0, NumTasks, [&]([[maybe_unused]] int i) {
int CurrentActive = ++ActiveTasks;
- LLVM_DEBUG(dbgs() << "Task " << i << ": Active tasks: " << CurrentActive
- << "\n");
int OldMax = MaxActiveTasks.load();
while (CurrentActive > OldMax)
MaxActiveTasks.compare_exchange_weak(OldMax, CurrentActive);
-
std::this_thread::sleep_for(std::chrono::milliseconds(20));
--ActiveTasks;
});
- LLVM_DEBUG(dbgs() << "ParallelFor finished. Max active tasks was "
- << MaxActiveTasks << ".\n");
EXPECT_LE(MaxActiveTasks, ConcurrencyLimit);
}
-TEST_F(JobserverStrategyTest, ParallelSortIsLimited) {
- // This test serves as an integration test to ensure parallelSort completes
- // correctly when running under the jobserver strategy. It doesn't directly
- // measure concurrency but verifies correctness.
+// Parent-side driver for parallelSort child test.
+TEST_F(JobserverStrategyTest, ParallelSortIsLimited_Subprocess) {
+ setenv("LLVM_JOBSERVER_TEST_CHILD", "1", 1);
+
+ std::string Executable =
+ sys::fs::getMainExecutable(TestMainArgv0, &JobserverTestAnchor);
+ ASSERT_FALSE(Executable.empty()) << "Failed to get main executable path";
+ SmallVector<StringRef, 4> Args{Executable,
+ "--gtest_filter=JobserverStrategyTest."
+ "ParallelSortIsLimited_SubprocessChild"};
+
+ std::string Error;
+ bool ExecFailed = false;
+ int RC = sys::ExecuteAndWait(Executable, Args, std::nullopt, {}, 0, 0, &Error,
+ &ExecFailed);
+ unsetenv("LLVM_JOBSERVER_TEST_CHILD");
+ ASSERT_FALSE(ExecFailed) << Error;
+ ASSERT_EQ(RC, 0) << "Executable failed with exit code " << RC;
+}
+
+// Child-side test: ensure parallelSort runs and completes correctly under the
+// jobserver strategy when it owns default executor initialization.
+TEST_F(JobserverStrategyTest, ParallelSortIsLimited_SubprocessChild) {
+ if (!getenv("LLVM_JOBSERVER_TEST_CHILD"))
+ GTEST_SKIP() << "Not running in child mode";
+
const int NumExplicitJobs = 3;
startMakeProxy(NumExplicitJobs);
parallel::strategy = jobserver_concurrency();
std::vector<int> V(1024);
- // Fill with random data
std::mt19937 randEngine;
std::uniform_int_distribution<int> dist;
for (int &i : V)
diff --git a/llvm/unittests/Support/LockFileManagerTest.cpp b/llvm/unittests/Support/LockFileManagerTest.cpp
index 627b2da..bd61b6c 100644
--- a/llvm/unittests/Support/LockFileManagerTest.cpp
+++ b/llvm/unittests/Support/LockFileManagerTest.cpp
@@ -12,7 +12,6 @@
#include "llvm/Testing/Support/Error.h"
#include "llvm/Testing/Support/SupportHelpers.h"
#include "gtest/gtest.h"
-#include <memory>
using namespace llvm;
using llvm::unittest::TempDir;
diff --git a/llvm/unittests/Support/ModRefTest.cpp b/llvm/unittests/Support/ModRefTest.cpp
index 9c13908..128501b 100644
--- a/llvm/unittests/Support/ModRefTest.cpp
+++ b/llvm/unittests/Support/ModRefTest.cpp
@@ -21,7 +21,7 @@ TEST(ModRefTest, PrintMemoryEffects) {
raw_string_ostream OS(S);
OS << MemoryEffects::none();
EXPECT_EQ(S, "ArgMem: NoModRef, InaccessibleMem: NoModRef, ErrnoMem: "
- "NoModRef, Other: NoModRef");
+ "NoModRef, Other: NoModRef, TargetMem0: NoModRef, TargetMem1: NoModRef");
}
} // namespace
diff --git a/llvm/unittests/Support/NativeFormatTests.cpp b/llvm/unittests/Support/NativeFormatTests.cpp
index ac04c5a..974709e 100644
--- a/llvm/unittests/Support/NativeFormatTests.cpp
+++ b/llvm/unittests/Support/NativeFormatTests.cpp
@@ -10,8 +10,6 @@
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
-#include <type_traits>
-
using namespace llvm;
namespace {
diff --git a/llvm/unittests/Support/OptimizedStructLayoutTest.cpp b/llvm/unittests/Support/OptimizedStructLayoutTest.cpp
index e8cd5f4..0bcae0d 100644
--- a/llvm/unittests/Support/OptimizedStructLayoutTest.cpp
+++ b/llvm/unittests/Support/OptimizedStructLayoutTest.cpp
@@ -25,7 +25,7 @@ class LayoutTest {
bool Verified = false;
public:
- LayoutTest() {}
+ LayoutTest() = default;
LayoutTest(const LayoutTest &) = delete;
LayoutTest &operator=(const LayoutTest &) = delete;
~LayoutTest() { assert(Verified); }
diff --git a/llvm/unittests/Support/ParallelTest.cpp b/llvm/unittests/Support/ParallelTest.cpp
index 041067d..c7ecc4e 100644
--- a/llvm/unittests/Support/ParallelTest.cpp
+++ b/llvm/unittests/Support/ParallelTest.cpp
@@ -15,7 +15,6 @@
#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS
#include "llvm/Support/ThreadPool.h"
#include "gtest/gtest.h"
-#include <array>
#include <random>
uint32_t array[1024 * 1024];
diff --git a/llvm/unittests/Support/Path.cpp b/llvm/unittests/Support/Path.cpp
index eb649de..51f65bf 100644
--- a/llvm/unittests/Support/Path.cpp
+++ b/llvm/unittests/Support/Path.cpp
@@ -1428,7 +1428,7 @@ TEST_F(FileSystemTest, FileMapping) {
fs::mapped_file_region mfr(fs::convertFDToNativeFile(FileDescriptor),
fs::mapped_file_region::readwrite, Size, 0, EC);
ASSERT_NO_ERROR(EC);
- std::copy(Val.begin(), Val.end(), mfr.data());
+ llvm::copy(Val, mfr.data());
// Explicitly add a 0.
mfr.data()[Val.size()] = 0;
@@ -1494,7 +1494,7 @@ TEST_F(FileSystemTest, FileMappingSync) {
// Write content through mapped memory.
ASSERT_NO_ERROR(EC);
- std::copy(Content.begin(), Content.end(), MFR.data());
+ llvm::copy(Content, MFR.data());
// Synchronize to file system.
ASSERT_FALSE((bool)MFR.sync());
diff --git a/llvm/unittests/Support/SignalsTest.cpp b/llvm/unittests/Support/SignalsTest.cpp
index 2964785..f871753 100644
--- a/llvm/unittests/Support/SignalsTest.cpp
+++ b/llvm/unittests/Support/SignalsTest.cpp
@@ -32,6 +32,11 @@ using testing::Not;
#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && \
(defined(__linux__) || defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || defined(__NetBSD__))
+// Test relies on the binary this test is linked into having a GNU build ID
+// note, which is not universally enabled by default (even when using Clang).
+// Disable until we can reliably detect whether this is the case and skip it if
+// not. See https://github.com/llvm/llvm-project/issues/168891.
+#if 0
TEST(SignalsTest, PrintsSymbolizerMarkup) {
auto Exit =
make_scope_exit([]() { unsetenv("LLVM_ENABLE_SYMBOLIZER_MARKUP"); });
@@ -51,6 +56,7 @@ TEST(SignalsTest, PrintsSymbolizerMarkup) {
// Backtrace line
EXPECT_THAT(Res, MatchesRegex(".*" TAG_BEGIN "bt:0:" P_REGEX ".*"));
}
+#endif
TEST(SignalsTest, SymbolizerMarkupDisabled) {
auto Exit = make_scope_exit([]() { unsetenv("LLVM_DISABLE_SYMBOLIZATION"); });
diff --git a/llvm/unittests/Support/SpecialCaseListTest.cpp b/llvm/unittests/Support/SpecialCaseListTest.cpp
index 750feda..812e0d3 100644
--- a/llvm/unittests/Support/SpecialCaseListTest.cpp
+++ b/llvm/unittests/Support/SpecialCaseListTest.cpp
@@ -308,43 +308,49 @@ TEST_F(SpecialCaseListTest, Version2) {
}
TEST_F(SpecialCaseListTest, DotSlash) {
- std::unique_ptr<SpecialCaseList> SCL2 = makeSpecialCaseList("[dot]\n"
- "fun:./foo\n"
- "src:./bar\n"
- "[not]\n"
- "fun:foo\n"
- "src:bar\n");
- std::unique_ptr<SpecialCaseList> SCL3 = makeSpecialCaseList("[dot]\n"
- "fun:./foo\n"
- "src:./bar\n"
- "[not]\n"
- "fun:foo\n"
- "src:bar\n",
- /*Version=*/3);
+ StringRef IgnoreList = "[dot]\n"
+ "fun:./foo\n"
+ "src:./bar\n"
+ "[not]\n"
+ "fun:foo\n"
+ "src:bar\n";
+ std::unique_ptr<SpecialCaseList> SCL2 = makeSpecialCaseList(IgnoreList);
+ std::unique_ptr<SpecialCaseList> SCL3 =
+ makeSpecialCaseList(IgnoreList, /*Version=*/3);
+ std::unique_ptr<SpecialCaseList> SCL4 = makeSpecialCaseList(IgnoreList,
+ /*Version=*/4);
EXPECT_TRUE(SCL2->inSection("dot", "fun", "./foo"));
EXPECT_TRUE(SCL3->inSection("dot", "fun", "./foo"));
+ EXPECT_TRUE(SCL4->inSection("dot", "fun", "./foo"));
EXPECT_FALSE(SCL2->inSection("dot", "fun", "foo"));
EXPECT_FALSE(SCL3->inSection("dot", "fun", "foo"));
+ EXPECT_FALSE(SCL4->inSection("dot", "fun", "foo"));
EXPECT_TRUE(SCL2->inSection("dot", "src", "./bar"));
EXPECT_FALSE(SCL3->inSection("dot", "src", "./bar"));
+ EXPECT_FALSE(SCL4->inSection("dot", "src", "./bar"));
EXPECT_FALSE(SCL2->inSection("dot", "src", "bar"));
EXPECT_FALSE(SCL3->inSection("dot", "src", "bar"));
+ EXPECT_FALSE(SCL4->inSection("dot", "src", "bar"));
EXPECT_FALSE(SCL2->inSection("not", "fun", "./foo"));
EXPECT_FALSE(SCL3->inSection("not", "fun", "./foo"));
+ EXPECT_FALSE(SCL4->inSection("not", "fun", "./foo"));
EXPECT_TRUE(SCL2->inSection("not", "fun", "foo"));
EXPECT_TRUE(SCL3->inSection("not", "fun", "foo"));
+ EXPECT_TRUE(SCL4->inSection("not", "fun", "foo"));
EXPECT_FALSE(SCL2->inSection("not", "src", "./bar"));
EXPECT_TRUE(SCL3->inSection("not", "src", "./bar"));
+ EXPECT_TRUE(SCL4->inSection("not", "src", "./bar"));
EXPECT_TRUE(SCL2->inSection("not", "src", "bar"));
EXPECT_TRUE(SCL3->inSection("not", "src", "bar"));
+ EXPECT_TRUE(SCL4->inSection("not", "src", "bar"));
}
TEST_F(SpecialCaseListTest, LinesInSection) {
diff --git a/llvm/unittests/Support/ThreadPool.cpp b/llvm/unittests/Support/ThreadPool.cpp
index aa7f874..7f72747 100644
--- a/llvm/unittests/Support/ThreadPool.cpp
+++ b/llvm/unittests/Support/ThreadPool.cpp
@@ -8,6 +8,7 @@
#include "llvm/Support/ThreadPool.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS
@@ -183,6 +184,56 @@ TYPED_TEST(ThreadPoolTest, Async) {
ASSERT_EQ(2, i.load());
}
+TYPED_TEST(ThreadPoolTest, AsyncMoveOnly) {
+ CHECK_UNSUPPORTED();
+ DefaultThreadPool Pool;
+ std::promise<int> p;
+ std::future<int> f = p.get_future();
+ Pool.async([this, p = std::move(p)]() mutable {
+ this->waitForMainThread();
+ p.set_value(42);
+ });
+ this->setMainThreadReady();
+ Pool.wait();
+ ASSERT_EQ(42, f.get());
+}
+
+TYPED_TEST(ThreadPoolTest, AsyncRAIICaptures) {
+ CHECK_UNSUPPORTED();
+ DefaultThreadPool Pool(hardware_concurrency(2));
+
+ // We use a task group and a non-atomic value to stress test that the chaining
+ // of tasks via a captured RAII object in fact chains and synchronizes within
+ // a group.
+ ThreadPoolTaskGroup Group(Pool);
+ int value = 0;
+
+ // Create an RAII object that when destroyed schedules more work. This makes
+ // it easy to check that the RAII is resolved at the same point as a task runs
+ // on the thread pool.
+ auto schedule_next = llvm::make_scope_exit([&Group, &value] {
+ // We sleep before scheduling the final task to make it much more likely
+ // that an incorrect implementation actually exbitits a bug. Without the
+ // sleep, we may get "lucky" and have the second task finish before the
+ // assertion below fails even with an incorrect implementaiton. The
+ // sleep is making _failures_ more reliable, it is not needed for
+ // correctness and this test should only flakily _pass_, never flakily
+ // fail.
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ Group.async([&value] { value = 42; });
+ });
+
+ // Now schedule the initial task, moving the RAII object to schedule the final
+ // task into its captures.
+ Group.async([schedule_next = std::move(schedule_next)]() {
+ // Nothing to do here, the captured RAII object does the work.
+ });
+
+ // Both tasks should complete here, synchronizing with the read of value.
+ Group.wait();
+ ASSERT_EQ(42, value);
+}
+
TYPED_TEST(ThreadPoolTest, GetFuture) {
CHECK_UNSUPPORTED();
DefaultThreadPool Pool(hardware_concurrency(2));
diff --git a/llvm/unittests/Support/YAMLIOTest.cpp b/llvm/unittests/Support/YAMLIOTest.cpp
index 283e5f8..7446c07 100644
--- a/llvm/unittests/Support/YAMLIOTest.cpp
+++ b/llvm/unittests/Support/YAMLIOTest.cpp
@@ -3221,12 +3221,12 @@ template <> struct TaggedScalarTraits<Scalar> {
template <> struct CustomMappingTraits<Map> {
static void inputOne(IO &IO, StringRef Key, Map &M) {
- IO.mapRequired(Key.str().c_str(), M[Key]);
+ IO.mapRequired(Key, M[Key]);
}
static void output(IO &IO, Map &M) {
for (auto &N : M)
- IO.mapRequired(N.getKey().str().c_str(), N.getValue());
+ IO.mapRequired(N.getKey(), N.getValue());
}
};
diff --git a/llvm/unittests/Support/raw_ostream_proxy_test.cpp b/llvm/unittests/Support/raw_ostream_proxy_test.cpp
index 864dda7..446e64a 100644
--- a/llvm/unittests/Support/raw_ostream_proxy_test.cpp
+++ b/llvm/unittests/Support/raw_ostream_proxy_test.cpp
@@ -40,8 +40,6 @@ public:
bool IsDisplayed = false;
};
-constexpr size_t BufferedNoPwriteSmallVectorStream::PreferredBufferSize;
-
TEST(raw_ostream_proxyTest, write) {
// Besides confirming that "write" works, this test confirms that the proxy
// takes on the buffer from the stream it's proxying, such that writes to the