[llvm] [VFS] Handle unavailable working directories when adding overlays (PR #228708)

via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 3 06:17:02 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-support

Author: Macro Terra (hongtaihu)

<details>
<summary>Changes</summary>

`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


---
Full diff: https://github.com/llvm/llvm-project/pull/228708.diff


2 Files Affected:

- (modified) llvm/lib/Support/VirtualFileSystem.cpp (+2-1) 
- (modified) llvm/unittests/Support/VirtualFileSystemTest.cpp (+18) 


``````````diff
diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp
index 5d0a3949e60ca..2e7b0ca80b5bc 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 507a0e4108a79..0000558967c78 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>();

``````````

</details>


https://github.com/llvm/llvm-project/pull/228708


More information about the llvm-commits mailing list