aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/Support/VirtualFileSystemTest.cpp
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2024-03-15 09:01:41 -0700
committerGitHub <noreply@github.com>2024-03-15 09:01:41 -0700
commit5a8a7ee9d12d7cd3680c7bc14a4750bd44d99c56 (patch)
treea09d36f67ec5df9cf40ab3ddaa514686c6bb9950 /llvm/unittests/Support/VirtualFileSystemTest.cpp
parent0ed7a5a9a1d4297e30c7992379ff292cd1aa3828 (diff)
downloadllvm-5a8a7ee9d12d7cd3680c7bc14a4750bd44d99c56.zip
llvm-5a8a7ee9d12d7cd3680c7bc14a4750bd44d99c56.tar.gz
llvm-5a8a7ee9d12d7cd3680c7bc14a4750bd44d99c56.tar.bz2
[llvm][vfs] Preserve paths for fallback/fallthrough in RedirectingFileSystem (#85307)
When we lookup in the external filesystem, do not remove . and .. components from the original path. For .. this is a correctness issue in the presence of symlinks, while for . it is simply better practice to preserve the original path to better match the behaviour of other filesystems. The only modification we need is to apply the working directory, since it could differ from the external filesystem. rdar://123655660
Diffstat (limited to 'llvm/unittests/Support/VirtualFileSystemTest.cpp')
-rw-r--r--llvm/unittests/Support/VirtualFileSystemTest.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/llvm/unittests/Support/VirtualFileSystemTest.cpp b/llvm/unittests/Support/VirtualFileSystemTest.cpp
index d4abbb4..695b093 100644
--- a/llvm/unittests/Support/VirtualFileSystemTest.cpp
+++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp
@@ -7,9 +7,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/VirtualFileSystem.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Errc.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SourceMgr.h"
@@ -3330,3 +3332,66 @@ TEST(RedirectingFileSystemTest, Used) {
EXPECT_TRUE(Redirecting1->hasBeenUsed());
EXPECT_FALSE(Redirecting2->hasBeenUsed());
}
+
+// Check that paths looked up in the external filesystem are unmodified, except
+// potentially to add the working directory. We cannot canonicalize away ..
+// in the presence of symlinks in the external filesystem.
+TEST(RedirectingFileSystemTest, ExternalPaths) {
+ struct InterceptorFS : llvm::vfs::ProxyFileSystem {
+ std::vector<std::string> SeenPaths;
+
+ InterceptorFS(IntrusiveRefCntPtr<FileSystem> UnderlyingFS)
+ : ProxyFileSystem(UnderlyingFS) {}
+
+ llvm::ErrorOr<llvm::vfs::Status> status(const Twine &Path) override {
+ SeenPaths.push_back(Path.str());
+ return ProxyFileSystem::status(Path);
+ }
+
+ llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
+ openFileForRead(const Twine &Path) override {
+ SeenPaths.push_back(Path.str());
+ return ProxyFileSystem::openFileForRead(Path);
+ }
+
+ std::error_code isLocal(const Twine &Path, bool &Result) override {
+ SeenPaths.push_back(Path.str());
+ return ProxyFileSystem::isLocal(Path, Result);
+ }
+
+ vfs::directory_iterator dir_begin(const Twine &Dir,
+ std::error_code &EC) override {
+ SeenPaths.push_back(Dir.str());
+ return ProxyFileSystem::dir_begin(Dir, EC);
+ }
+ };
+
+ std::error_code EC;
+ auto BaseFS = makeIntrusiveRefCnt<DummyFileSystem>();
+ BaseFS->setCurrentWorkingDirectory("/cwd");
+ auto CheckFS = makeIntrusiveRefCnt<InterceptorFS>(BaseFS);
+ auto FS = vfs::RedirectingFileSystem::create({}, /*UseExternalNames=*/false,
+ *CheckFS);
+
+ FS->status("/a/../b");
+ FS->openFileForRead("c");
+ FS->exists("./d");
+ bool IsLocal = false;
+ FS->isLocal("/e/./../f", IsLocal);
+ FS->dir_begin(".././g", EC);
+
+ std::vector<std::string> Expected{"/a/../b", "/cwd/c", "/cwd/./d",
+ "/e/./../f", "/cwd/.././g"};
+
+ EXPECT_EQ(CheckFS->SeenPaths, Expected);
+
+ CheckFS->SeenPaths.clear();
+ FS->setRedirection(vfs::RedirectingFileSystem::RedirectKind::Fallback);
+ FS->status("/a/../b");
+ FS->openFileForRead("c");
+ FS->exists("./d");
+ FS->isLocal("/e/./../f", IsLocal);
+ FS->dir_begin(".././g", EC);
+
+ EXPECT_EQ(CheckFS->SeenPaths, Expected);
+}