llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang @llvm/pr-subscribers-llvm-support Author: None (yelleyee) <details> <summary>Changes</summary> Add a new feature allowing root(/) directory remap by breaking the assumption that remap root must be a directory. Now the config below will be allowed. Directory-remap config of root(/) is not allowed in previous impl. Config list below will cause assertion failure in `uniqueOverlayTree`. ```json 'name': '/', 'type': 'directory-remap', 'external-contents': '/xxxx/xxx' ``` Assertion failed stack is attached below: ``` clang -cc1 -ferror-limit 19 -fcolor-diagnostics -o /dev/null -disable-free -emit-obj -x c a.c -tune-cpu generic -target-cpu x86-64 -triple x86_64-unknown-linux-gnu -resource-dir ///MY_ROOT///Source/llvm-project/build/lib/clang/18 -isystem ///MY_ROOT///Source/llvm-project/build/lib/clang/18/include -isystem /usr/local/include -isystem /usr/lib/gcc/x86_64-linux-gnu/9/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=gnu17 -fmath-errno -fno-implicit-modules -pic-level 2 -pic-is-pie -fgnuc-version=4.2.1 -ffp-contract=on -fno-experimental-relative-c++-abi-vtables -fno-file-reproducible -O0 -fdebug-compilation-dir=///MY_ROOT_1///gitWorkSpace/test -fcoverage-compilation-dir=///MY_ROOT_1///gitWorkSpace/test -faddrsig -mrelax-all -debugger-tuning=gdb -funwind-tables=2 -mconstructor-aliases -clear-ast-before-backend -main-file-name a.c -mframe-pointer=all -fdiagnostics-hotness-threshold=0 -fdiagnostics-misexpect-tolerance=0 -D __GCC_HAVE_DWARF2_CFI_ASM=1 -ivfsoverlay vfs.yaml clang: ///MY_ROOT///llvm-project/llvm/lib/Support/VirtualFileSystem.cpp:1749: void llvm::vfs::RedirectingFileSystemParser::uniqueOverlayTree(llvm::vfs::RedirectingFileSystem*, llvm::vfs::RedirectingFileSystem::Entry*, llvm::vfs::RedirectingFileSystem::Entry*): Assertion `NewParentE && "Parent entry must exist"' failed. PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script. Stack dump: 0. Program arguments: clang -cc1 -ferror-limit 19 -fcolor-diagnostics -o /dev/null -disable-free -emit-obj -x c a.c -tune-cpu generic -target-cpu x86-64 -triple x86_64-unknown-linux-gnu -resource-dir ///MY_ROOT///Source/llvm-project/build/lib/clang/18 -isystem ///MY_ROOT///Source/llvm-project/build/lib/clang/18/include -isystem /usr/local/include -isystem /usr/lib/gcc/x86_64-linux-gnu/9/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=gnu17 -fmath-errno -fno-implicit-modules -pic-level 2 -pic-is-pie -fgnuc-version=4.2.1 -ffp-contract=on -fno-experimental-relative-c++-abi-vtables -fno-file-reproducible -O0 -fdebug-compilation-dir=///MY_ROOT_1///gitWorkSpace/test -fcoverage-compilation-dir=///MY_ROOT_1///gitWorkSpace/test -faddrsig -mrelax-all -debugger-tuning=gdb -funwind-tables=2 -mconstructor-aliases -clear-ast-before-backend -main-file-name a.c -mframe-pointer=all -fdiagnostics-hotness-threshold=0 -fdiagnostics-misexpect-tolerance=0 -D __GCC_HAVE_DWARF2_CFI_ASM=1 -ivfsoverlay vfs.yaml Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it): 0 libLLVMSupport.so.16 0x00007f3786891a7c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 82 1 libLLVMSupport.so.16 0x00007f3786891e47 2 libLLVMSupport.so.16 0x00007f378688f72a llvm::sys::RunSignalHandlers() + 159 3 libLLVMSupport.so.16 0x00007f37868913b0 4 libc.so.6 0x00007f378606f090 5 libc.so.6 0x00007f378606f00b gsignal + 203 6 libc.so.6 0x00007f378604e859 abort + 299 7 libc.so.6 0x00007f378604e729 8 libc.so.6 0x00007f378605ffd6 9 libLLVMSupport.so.16 0x00007f37868320d2 10 libLLVMSupport.so.16 0x00007f3786834be3 11 libLLVMSupport.so.16 0x00007f3786822f00 llvm::vfs::RedirectingFileSystem::create(std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, void (*)(llvm::SMDiagnostic const&, void*), llvm::StringRef, void*, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>) + 994 12 libLLVMSupport.so.16 0x00007f3786825b06 llvm::vfs::getVFSFromYAML(std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, void (*)(llvm::SMDiagnostic const&, void*), llvm::StringRef, void*, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>) + 169 13 libclangFrontend.so.16 0x00007f378c6145c0 clang::createVFSFromOverlayFiles(llvm::ArrayRef<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, clang::DiagnosticsEngine&, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>) + 520 14 libclangFrontend.so.16 0x00007f378c614392 clang::createVFSFromCompilerInvocation(clang::CompilerInvocation const&, clang::DiagnosticsEngine&, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>) + 138 15 libclangFrontend.so.16 0x00007f378c6142e1 clang::createVFSFromCompilerInvocation(clang::CompilerInvocation const&, clang::DiagnosticsEngine&) + 75 16 libclangFrontend.so.16 0x00007f378c56f6b9 clang::CompilerInstance::createFileManager(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>) + 175 17 libclangFrontend.so.16 0x00007f378c661b99 clang::FrontendAction::BeginSourceFile(clang::CompilerInstance&, clang::FrontendInputFile const&) + 4027 18 libclangFrontend.so.16 0x00007f378c5738f9 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 919 19 libclangFrontendTool.so.16 0x00007f379224adb6 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 937 20 clang 0x0000557f7ebde56b cc1_main(llvm::ArrayRef<char const*>, char const*, void*) + 1679 21 clang 0x0000557f7ebcb4ba 22 clang 0x0000557f7ebcbc8c clang_main(int, char**) + 1442 23 clang 0x0000557f7ec01ff5 main + 36 24 libc.so.6 0x00007f3786050083 __libc_start_main + 243 25 clang 0x0000557f7ebc99ce _start + 46 [1] 116965 abort clang -cc1 -ferror-limit 19 -fcolor-diagnostics -o /dev/null -disable-free - ``` --- Full diff: https://github.com/llvm/llvm-project/pull/83766.diff 4 Files Affected: - (added) clang/test/VFS/Inputs/system-root-remap.yaml (+12) - (added) clang/test/VFS/system-root-remap.c (+14) - (modified) llvm/lib/Support/VirtualFileSystem.cpp (+18) - (modified) llvm/unittests/Support/VirtualFileSystemTest.cpp (+42) ``````````diff diff --git a/clang/test/VFS/Inputs/system-root-remap.yaml b/clang/test/VFS/Inputs/system-root-remap.yaml new file mode 100644 index 00000000000000..43d25fcc952236 --- /dev/null +++ b/clang/test/VFS/Inputs/system-root-remap.yaml @@ -0,0 +1,12 @@ +{ + 'version': 0, + 'use-external-names': false, + 'redirecting-with': 'redirect-only' + 'roots': [ + { + 'name': '/', + 'type': 'directory-remap', + 'external-contents': 'EXTERNAL_DIR' + } + ] +} diff --git a/clang/test/VFS/system-root-remap.c b/clang/test/VFS/system-root-remap.c new file mode 100644 index 00000000000000..f4168b75f29909 --- /dev/null +++ b/clang/test/VFS/system-root-remap.c @@ -0,0 +1,14 @@ +// RUN: mkdir -p %t +// RUN: cd %t +// RUN: sed -e "s@INPUT_DIR@%{/S:regex_replacement}/Inputs@g" -e "s@EXTERNAL_DIR@%{/t:regex_replacement}@g" %S/Inputs/system-root-remap.yaml > %t.yaml +// RUN: mkdir -p %t%t +// RUN: cp %S/Inputs/actual_header.h %t%t/not_real.h +// RUN: mkdir -p %t%S +// RUN: cp %s %t%S +// RUN: %clang_cc1 -Werror -I . -vfsoverlay %t.yaml -fsyntax-only -working-directory=%t %s + +#include "not_real.h" + +void foo(void) { + bar(); +} diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp index 051dd2a67d120f..1e18cbced9effd 100644 --- a/llvm/lib/Support/VirtualFileSystem.cpp +++ b/llvm/lib/Support/VirtualFileSystem.cpp @@ -1747,6 +1747,10 @@ class llvm::vfs::RedirectingFileSystemParser { void uniqueOverlayTree(RedirectingFileSystem *FS, RedirectingFileSystem::Entry *SrcE, RedirectingFileSystem::Entry *NewParentE = nullptr) { + if (NewParentE) { + assert(NewParentE->getKind() == RedirectingFileSystem::EK_Directory && + "NewParentE must be a directory entry or nullptr"); + } StringRef Name = SrcE->getName(); switch (SrcE->getKind()) { case RedirectingFileSystem::EK_Directory: { @@ -1756,12 +1760,26 @@ class llvm::vfs::RedirectingFileSystemParser { // is parsed. This only leads to redundant walks, ignore it. if (!Name.empty()) NewParentE = lookupOrCreateEntry(FS, Name, NewParentE); + if (NewParentE->getKind() != RedirectingFileSystem::EK_Directory) { + // Found non directory entry, no need to generate the left nodes. + break; + } for (std::unique_ptr<RedirectingFileSystem::Entry> &SubEntry : llvm::make_range(DE->contents_begin(), DE->contents_end())) uniqueOverlayTree(FS, SubEntry.get(), NewParentE); break; } case RedirectingFileSystem::EK_DirectoryRemap: { + // Root DirectoryRemap: + // name: "/" + // external-name: "xxxx" + if (!NewParentE) { + auto *DR = cast<RedirectingFileSystem::DirectoryRemapEntry>(SrcE); + FS->Roots.push_back( + std::make_unique<RedirectingFileSystem::DirectoryRemapEntry>( + Name, DR->getExternalContentsPath(), DR->getUseName())); + break; + } assert(NewParentE && "Parent entry must exist"); auto *DR = cast<RedirectingFileSystem::DirectoryRemapEntry>(SrcE); auto *DE = cast<RedirectingFileSystem::DirectoryEntry>(NewParentE); diff --git a/llvm/unittests/Support/VirtualFileSystemTest.cpp b/llvm/unittests/Support/VirtualFileSystemTest.cpp index d4abbb4345873c..0a77d8b13eca0e 100644 --- a/llvm/unittests/Support/VirtualFileSystemTest.cpp +++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp @@ -1715,6 +1715,48 @@ TEST_F(VFSFromYAMLTest, MappedRoot) { EXPECT_EQ(0, NumDiagnostics); } +TEST_F(VFSFromYAMLTest, MappedSysRoot) { + IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + Lower->addDirectory("//root/foo/bar"); + Lower->addRegularFile("//root/foo/bar/a"); + IntrusiveRefCntPtr<vfs::FileSystem> FS = + getFromYAMLString("{ 'roots': [\n" + "{\n" + " 'type': 'directory-remap',\n" + " 'name': '/',\n" + " 'external-contents': '//root/foo/bar'\n" + "}\n" + "]\n" + "}", + Lower); + ASSERT_NE(FS.get(), nullptr); + + IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( + new vfs::OverlayFileSystem(Lower)); + O->pushOverlay(FS); + + // file + ErrorOr<vfs::Status> S = O->status("/a"); + ASSERT_FALSE(S.getError()); + EXPECT_EQ("//root/foo/bar/a", S->getName()); + EXPECT_TRUE(S->ExposesExternalVFSPath); + + ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a"); + EXPECT_EQ("//root/foo/bar/a", SLower->getName()); + EXPECT_TRUE(S->equivalent(*SLower)); + EXPECT_FALSE(SLower->ExposesExternalVFSPath); + + // file after opening + auto OpenedF = O->openFileForRead("/a"); + ASSERT_FALSE(OpenedF.getError()); + auto OpenedS = (*OpenedF)->status(); + ASSERT_FALSE(OpenedS.getError()); + EXPECT_EQ("//root/foo/bar/a", OpenedS->getName()); + EXPECT_TRUE(OpenedS->ExposesExternalVFSPath); + + EXPECT_EQ(0, NumDiagnostics); +} + TEST_F(VFSFromYAMLTest, RemappedDirectoryOverlay) { IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); Lower->addDirectory("//root/foo"); `````````` </details> https://github.com/llvm/llvm-project/pull/83766 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits