diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp --- a/clang-tools-extra/clangd/TUScheduler.cpp +++ b/clang-tools-extra/clangd/TUScheduler.cpp @@ -919,7 +919,9 @@ llvm::unique_function Action) { if (!PreambleTasks) return Action(); - PreambleTasks->runAsync(Name, std::move(Action)); + auto ActionWithCtx = [Ctx = Context::current().clone(), + Action = std::move(Action)]() mutable { Action(); }; + PreambleTasks->runAsync(Name, std::move(ActionWithCtx)); } void TUScheduler::runWithAST( diff --git a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp --- a/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp +++ b/clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp @@ -688,6 +688,24 @@ S.run("add 2", [&] { Counter += 2; }); ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10))); EXPECT_EQ(Counter.load(), 3); + + Notification OutsideCtxDestroyed; + Notification ScopeExit; + Counter.store(0); + { + WithContextValue Context(llvm::make_scope_exit([&] { + ++Counter; + ScopeExit.notify(); + })); + S.run("props context", [&] { + OutsideCtxDestroyed.wait(); + // scope exit shouldn't be called until run finishes. + EXPECT_THAT(Counter.load(), 0); + }); + } + OutsideCtxDestroyed.notify(); + ScopeExit.wait(); + EXPECT_THAT(Counter.load(), 1); } TEST_F(TUSchedulerTests, TUStatus) {