[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