Index: clangd/index/Background.cpp =================================================================== --- clangd/index/Background.cpp +++ clangd/index/Background.cpp @@ -121,6 +121,7 @@ } else { AbsolutePath = Cmd.Directory; llvm::sys::path::append(AbsolutePath, Cmd.Filename); + llvm::sys::path::remove_dots(AbsolutePath, true); } return AbsolutePath; } Index: unittests/clangd/BackgroundIndexTests.cpp =================================================================== --- unittests/clangd/BackgroundIndexTests.cpp +++ unittests/clangd/BackgroundIndexTests.cpp @@ -44,12 +44,14 @@ llvm::Error storeShard(llvm::StringRef ShardIdentifier, IndexFileOut Shard) const override { std::lock_guard Lock(StorageMu); + AccessedPaths.insert(ShardIdentifier); Storage[ShardIdentifier] = llvm::to_string(Shard); return llvm::Error::success(); } std::unique_ptr loadShard(llvm::StringRef ShardIdentifier) const override { std::lock_guard Lock(StorageMu); + AccessedPaths.insert(ShardIdentifier); if (Storage.find(ShardIdentifier) == Storage.end()) { return nullptr; } @@ -62,6 +64,8 @@ CacheHits++; return llvm::make_unique(std::move(*IndexFile)); } + + mutable llvm::StringSet<> AccessedPaths; }; class BackgroundIndexTest : public ::testing::Test { @@ -428,5 +432,34 @@ Contains(AllOf(Named("new_func"), Declared(), Not(Defined())))); } +TEST_F(BackgroundIndexTest, NoDotsInAbsPath) { + MockFSProvider FS; + llvm::StringMap Storage; + size_t CacheHits = 0; + MemoryShardStorage MSS(Storage, CacheHits); + OverlayCDB CDB(/*Base=*/nullptr); + BackgroundIndex Idx(Context::empty(), FS, CDB, + [&](llvm::StringRef) { return &MSS; }); + + tooling::CompileCommand Cmd; + FS.Files[testPath("root/A.cc")] = ""; + Cmd.Filename = "../A.cc"; + Cmd.Directory = testPath("root/build"); + Cmd.CommandLine = {"clang++", "../A.cc"}; + CDB.setCompileCommand(testPath("root/build/../A.cc"), Cmd); + + FS.Files[testPath("root/B.cc")] = ""; + Cmd.Filename = "./B.cc"; + Cmd.Directory = testPath("root"); + Cmd.CommandLine = {"clang++", "./B.cc"}; + CDB.setCompileCommand(testPath("root/./B.cc"), Cmd); + + ASSERT_TRUE(Idx.blockUntilIdleForTest()); + for (llvm::StringRef AbsPath : MSS.AccessedPaths.keys()) { + EXPECT_FALSE(AbsPath.contains("./")) << AbsPath; + EXPECT_FALSE(AbsPath.contains("../")) << AbsPath; + } +} + } // namespace clangd } // namespace clang