diff --git a/clang/test/VFS/relative-path-errors.c b/clang/test/VFS/relative-path-errors.c new file mode 100644 --- /dev/null +++ b/clang/test/VFS/relative-path-errors.c @@ -0,0 +1,8 @@ +// RUN: mkdir -p %t +// RUN: cd %t +// RUN: echo '{"roots": [],"version": 0}' > %t.yaml +// RUN: cp %s main.c +// RUN: not %clang_cc1 -ivfsoverlay %t.yaml main.c 2>&1 | FileCheck %s + +// CHECK: {{^}}main.c:8:1: error: +foobarbaz diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp --- a/llvm/lib/Support/VirtualFileSystem.cpp +++ b/llvm/lib/Support/VirtualFileSystem.cpp @@ -2003,14 +2003,14 @@ } // namespace ErrorOr> -RedirectingFileSystem::openFileForRead(const Twine &Path_) { - SmallString<256> Path; - Path_.toVector(Path); +RedirectingFileSystem::openFileForRead(const Twine &Path) { + SmallString<256> CanonicalPath; + Path.toVector(CanonicalPath); - if (std::error_code EC = makeCanonical(Path)) + if (std::error_code EC = makeCanonical(CanonicalPath)) return EC; - ErrorOr Result = lookupPath(Path); + ErrorOr Result = lookupPath(CanonicalPath); if (!Result) { if (shouldFallBackToExternalFS(Result.getError())) return ExternalFS->openFileForRead(Path); @@ -2036,7 +2036,7 @@ // FIXME: Update the status with the name and VFSMapped. Status S = getRedirectedFileStatus( - Path, RE->useExternalName(UseExternalNames), *ExternalStatus); + CanonicalPath, RE->useExternalName(UseExternalNames), *ExternalStatus); return std::unique_ptr( std::make_unique(std::move(*ExternalFile), S)); } diff --git a/llvm/unittests/Support/VirtualFileSystemTest.cpp b/llvm/unittests/Support/VirtualFileSystemTest.cpp --- a/llvm/unittests/Support/VirtualFileSystemTest.cpp +++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp @@ -1607,6 +1607,26 @@ EXPECT_EQ(0, NumDiagnostics); } +TEST_F(VFSFromYAMLTest, RelativePathFallthrough) { + IntrusiveRefCntPtr BaseFS = + new vfs::InMemoryFileSystem; + BaseFS->addFile("//root/foo/a", 0, MemoryBuffer::getMemBuffer("contents of a")); + ASSERT_FALSE(BaseFS->setCurrentWorkingDirectory("//root/foo")); + auto RemappedFS = vfs::RedirectingFileSystem::create( + {}, /*UseExternalNames=*/false, *BaseFS); + + auto OpenedF = RemappedFS->openFileForRead("a"); + ASSERT_FALSE(OpenedF.getError()); + llvm::ErrorOr Name = (*OpenedF)->getName(); + ASSERT_FALSE(Name.getError()); + auto OpenedS = (*OpenedF)->status(); + ASSERT_FALSE(OpenedS.getError()); + EXPECT_EQ("a", Name.get()); + EXPECT_EQ("a", OpenedS->getName()); + EXPECT_FALSE(OpenedS->IsVFSMapped); + EXPECT_EQ(0, NumDiagnostics); +} + TEST_F(VFSFromYAMLTest, CaseInsensitive) { IntrusiveRefCntPtr Lower(new DummyFileSystem()); Lower->addRegularFile("//root/foo/bar/a");