[llvm] [VFS] Handle unavailable working directories when adding overlays (PR #228708)
Macro Terra via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 3 06:16:25 PDT 2026
https://github.com/hongtaihu created https://github.com/llvm/llvm-project/pull/228708
`OverlayFileSystem::pushOverlay()` synchronizes the added file system's
working directory with the base file system. It currently calls `.get()`
on the result of `getCurrentWorkingDirectory()` without checking for an
error.
The query can fail when the process's current working directory has been
deleted. In clangd, a rename request creates an overlay for unsaved files
and reaches this unchecked access, triggering an `ErrorOr` assertion.
Only synchronize the working directory when the query succeeds. On
failure, retain the added file system's existing working directory. This
follows the pattern already used by the `RedirectingFileSystem`
constructor.
Add a unit test with a file system whose working directory query returns
`no_such_file_or_directory`. Verify that adding the overlay succeeds,
preserves its existing working directory, and allows absolute-path file
lookup.
Validation on the existing local assertions build, before rebasing onto
current main:
- The new unit test passes.
- Replaying the reported clangd scenario changes from an assertion failure
to a completed rename response and normal process exit.
Fixes #210481
Assisted by Codex
>From 9aacbbf09841f94e8a59314ac8619b0aa462b7dc Mon Sep 17 00:00:00 2001
From: hongtaihu <13541229370 at qq.com>
Date: Sat, 3 Oct 2026 21:16:07 +0800
Subject: [PATCH] [VFS] Handle unavailable working directories when adding
overlays
`OverlayFileSystem::pushOverlay()` synchronizes the added file system's
working directory with the base file system. It currently calls `.get()`
on the result of `getCurrentWorkingDirectory()` without checking for an
error.
The query can fail when the process's current working directory has been
deleted. In clangd, a rename request creates an overlay for unsaved files
and reaches this unchecked access, triggering an `ErrorOr` assertion.
Only synchronize the working directory when the query succeeds. On
failure, retain the added file system's existing working directory. This
follows the pattern already used by the `RedirectingFileSystem`
constructor.
Add a unit test with a file system whose working directory query returns
`no_such_file_or_directory`. Verify that adding the overlay succeeds,
preserves its existing working directory, and allows absolute-path file
lookup.
Validation on the existing local assertions build, before rebasing onto
current main:
- The new unit test passes.
- Replaying the reported clangd scenario changes from an assertion failure
to a completed rename response and normal process exit.
Fixes #210481
Assisted by Codex
---
llvm/lib/Support/VirtualFileSystem.cpp | 3 ++-
.../Support/VirtualFileSystemTest.cpp | 18 ++++++++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp
index 5d0a3949e60ca0..2e7b0ca80b5bcf 100644
--- a/llvm/lib/Support/VirtualFileSystem.cpp
+++ b/llvm/lib/Support/VirtualFileSystem.cpp
@@ -481,7 +481,8 @@ void OverlayFileSystem::pushOverlay(IntrusiveRefCntPtr<FileSystem> FS) {
FSList.push_back(FS);
// Synchronize added file systems by duplicating the working directory from
// the first one in the list.
- FS->setCurrentWorkingDirectory(getCurrentWorkingDirectory().get());
+ if (auto WorkingDir = getCurrentWorkingDirectory())
+ FS->setCurrentWorkingDirectory(*WorkingDir);
}
ErrorOr<Status> OverlayFileSystem::status(const Twine &Path) {
diff --git a/llvm/unittests/Support/VirtualFileSystemTest.cpp b/llvm/unittests/Support/VirtualFileSystemTest.cpp
index 507a0e4108a79e..0000558967c78b 100644
--- a/llvm/unittests/Support/VirtualFileSystemTest.cpp
+++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp
@@ -312,6 +312,24 @@ TEST(VirtualFileSystemTest, GetRealPathInOverlay) {
EXPECT_EQ(RealPath.str(), "/symlink");
}
+TEST(VirtualFileSystemTest, OverlayWithUnavailableWorkingDirectory) {
+ class UnavailableWorkingDirectoryFS : public DummyFileSystem {
+ ErrorOr<std::string> getCurrentWorkingDirectory() const override {
+ return make_error_code(errc::no_such_file_or_directory);
+ }
+ };
+ auto Base = makeIntrusiveRefCnt<UnavailableWorkingDirectoryFS>();
+ auto Upper = makeIntrusiveRefCnt<DummyFileSystem>();
+ Upper->setCurrentWorkingDirectory("/upper");
+ Upper->addRegularFile("/foo");
+ auto Overlay = makeIntrusiveRefCnt<vfs::OverlayFileSystem>(Base);
+ Overlay->pushOverlay(Upper);
+ EXPECT_EQ(Overlay->getCurrentWorkingDirectory().getError(),
+ errc::no_such_file_or_directory);
+ EXPECT_EQ(*Upper->getCurrentWorkingDirectory(), "/upper");
+ EXPECT_TRUE(Overlay->status("/foo"));
+}
+
TEST(VirtualFileSystemTest, OverlayFiles) {
auto Base = makeIntrusiveRefCnt<DummyFileSystem>();
auto Middle = makeIntrusiveRefCnt<DummyFileSystem>();
More information about the llvm-commits
mailing list