diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp index b641e4a0f0abb..266944ee730cb 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp @@ -366,7 +366,8 @@ class DepScanFile final : public llvm::vfs::File { llvm::ErrorOr> getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) override { - return std::move(Buffer); + return llvm::MemoryBuffer::getMemBuffer(Buffer->getMemBufferRef(), + RequiresNullTerminator); } std::error_code close() override { return {}; } diff --git a/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp b/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp index 023c02ddaa3e4..cdb0ce2100d60 100644 --- a/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp +++ b/clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp @@ -13,6 +13,39 @@ using namespace clang::tooling::dependencies; +TEST(DependencyScanningFilesystem, OpenFileAndGetBufferRepeatedly) { + auto InMemoryFS = llvm::makeIntrusiveRefCnt(); + InMemoryFS->setCurrentWorkingDirectory("/"); + InMemoryFS->addFile("/foo", 0, llvm::MemoryBuffer::getMemBuffer("content")); + + DependencyScanningFilesystemSharedCache SharedCache; + DependencyScanningWorkerFilesystem DepFS(SharedCache, InMemoryFS); + + auto FileOrErr1 = DepFS.openFileForRead("foo"); + auto FileOrErr2 = DepFS.openFileForRead("foo"); + ASSERT_EQ(FileOrErr1.getError(), std::error_code{}); + ASSERT_EQ(FileOrErr1.getError(), std::error_code{}); + std::unique_ptr File1 = std::move(*FileOrErr1); + std::unique_ptr File2 = std::move(*FileOrErr2); + ASSERT_NE(File1, nullptr); + ASSERT_NE(File2, nullptr); + auto BufOrErr11 = File1->getBuffer("buf11"); + auto BufOrErr12 = File1->getBuffer("buf12"); + auto BufOrErr21 = File1->getBuffer("buf21"); + ASSERT_EQ(BufOrErr11.getError(), std::error_code{}); + ASSERT_EQ(BufOrErr12.getError(), std::error_code{}); + ASSERT_EQ(BufOrErr21.getError(), std::error_code{}); + std::unique_ptr Buf11 = std::move(*BufOrErr11); + std::unique_ptr Buf12 = std::move(*BufOrErr12); + std::unique_ptr Buf21 = std::move(*BufOrErr21); + ASSERT_NE(Buf11, nullptr); + ASSERT_NE(Buf12, nullptr); + ASSERT_NE(Buf21, nullptr); + ASSERT_EQ(Buf11->getBuffer().data(), Buf12->getBuffer().data()); + ASSERT_EQ(Buf11->getBuffer().data(), Buf21->getBuffer().data()); + EXPECT_EQ(Buf11->getBuffer(), "content"); +} + TEST(DependencyScanningWorkerFilesystem, CacheStatusFailures) { auto InMemoryFS = llvm::makeIntrusiveRefCnt();