https://github.com/kimgr created https://github.com/llvm/llvm-project/pull/174575
Demonstrates: - A bug where files resolved adjacent to the includer (and not from the header search path) do not get their include name mapped - A surprising behavior where include name mappings are overwritten if files are included by more than one name From 22353c413d871124e65bc2d1b5610a1cd27c88dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20Gr=C3=A4sman?= <[email protected]> Date: Tue, 6 Jan 2026 12:35:02 +0100 Subject: [PATCH] Add unit test for #174482 Demonstrates: - A bug where files resolved adjacent to the includer (and not from the header search path) do not get their include name mapped - A surprising behavior where include name mappings are overwritten if files are included by more than one name --- clang/unittests/Lex/HeaderSearchTest.cpp | 60 ++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/clang/unittests/Lex/HeaderSearchTest.cpp b/clang/unittests/Lex/HeaderSearchTest.cpp index 0213bfeb8e221..b5de494e10110 100644 --- a/clang/unittests/Lex/HeaderSearchTest.cpp +++ b/clang/unittests/Lex/HeaderSearchTest.cpp @@ -37,14 +37,15 @@ class HeaderSearchTest : public ::testing::Test { Target = TargetInfo::CreateTargetInfo(Diags, *TargetOpts); } - void addSearchDir(llvm::StringRef Dir) { + void addSearchDir(llvm::StringRef Dir, bool IsSystem = false) { VFS->addFile( Dir, 0, llvm::MemoryBuffer::getMemBuffer(""), /*User=*/std::nullopt, /*Group=*/std::nullopt, llvm::sys::fs::file_type::directory_file); auto DE = FileMgr.getOptionalDirectoryRef(Dir); assert(DE); - auto DL = DirectoryLookup(*DE, SrcMgr::C_User, /*isFramework=*/false); - Search.AddSearchPath(DL, /*isAngled=*/false); + auto DL = DirectoryLookup(*DE, IsSystem ? SrcMgr::C_System : SrcMgr::C_User, + /*isFramework=*/false); + Search.AddSearchPath(DL, /*isAngled=*/IsSystem); } void addFrameworkSearchDir(llvm::StringRef Dir, bool IsSystem = true) { @@ -389,5 +390,58 @@ TEST_F(HeaderSearchTest, HeaderFileInfoMerge) { EXPECT_FALSE(Search.getExistingFileInfo(TextualFE)->External); } +TEST_F(HeaderSearchTest, IncludeNamesLookup) { + auto AddHeader = [&](const std::string &HeaderPath) -> FileEntryRef { + VFS->addFile(HeaderPath, 0, + llvm::MemoryBuffer::getMemBufferCopy("", HeaderPath), + /*User=*/std::nullopt, /*Group=*/std::nullopt, + llvm::sys::fs::file_type::regular_file); + return *FileMgr.getOptionalFileRef(HeaderPath); + }; + + auto LookupFile = + [&](llvm::StringRef Filename, bool IsAngled, + llvm::ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>> + Includers) -> OptionalFileEntryRef { + return Search.LookupFile( + Filename, SourceLocation(), /*isAngled=*/IsAngled, + /*FromDir=*/nullptr, + /*CurDir=*/nullptr, Includers, /*SearchPath=*/nullptr, + /*RelativePath=*/nullptr, /*RequestingModule=*/nullptr, + /*SuggestedModule=*/nullptr, /*IsMapped=*/nullptr, + /*IsFrameworkFound=*/nullptr); + }; + + AddHeader("/sys/bits/textual.h"); + AddHeader("/sys/bits/detail.h"); + AddHeader("/sys/system.h"); + addSearchDir("/sys", /*IsSystem=*/true); + + // main.c: #include <system.h> + auto SystemFile = LookupFile("system.h", true, {}); + ASSERT_TRUE(SystemFile.has_value()); + // system.h: #include <bits/detail.h> + auto DetailFile = + LookupFile("bits/detail.h", true, {{SystemFile, SystemFile->getDir()}}); + ASSERT_TRUE(DetailFile.has_value()); + // bits/detail.h: #include "textual.h" + auto TextualFile = + LookupFile("textual.h", false, {{DetailFile, DetailFile->getDir()}}); + ASSERT_TRUE(TextualFile.has_value()); + + EXPECT_EQ(Search.getIncludeNameForHeader(*SystemFile), "system.h"); + EXPECT_EQ(Search.getIncludeNameForHeader(*DetailFile), "bits/detail.h"); + // BUG: LookupFile does not add an include name for textual.h. + EXPECT_EQ(Search.getIncludeNameForHeader(*TextualFile), "textual.h"); + + // bits/detail.h: #include "bits/textual.h" + auto R = + LookupFile("bits/textual.h", false, {{DetailFile, DetailFile->getDir()}}); + ASSERT_TRUE(R.has_value()); + // SURPRISE? TextualFile is remapped under the hood because "bits/textual.h" + // resolves to the same file as "textual.h". + EXPECT_EQ(Search.getIncludeNameForHeader(*TextualFile), "bits/textual.h"); +} + } // namespace } // namespace clang _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
