[llvm] [SpecialCaseList] Remove ./ from file path (PR #162437)

via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 8 01:19:05 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-support

Author: Vitaly Buka (vitalybuka)

<details>
<summary>Changes</summary>

This extends approach used in WarningsSpecialCaseList
on other types of SpecialCaseList.

SpecialCaseList will remove leading "./" from the Query
for prefixes which looks like file names.

Now affected prefixes are "src", "!src", "mainfile", "source".

To avoid breaking users, this behavior is enabled for
files starting "#!special-case-list-v3".


---
Full diff: https://github.com/llvm/llvm-project/pull/162437.diff


3 Files Affected:

- (modified) llvm/include/llvm/Support/SpecialCaseList.h (+1) 
- (modified) llvm/lib/Support/SpecialCaseList.cpp (+9) 
- (modified) llvm/unittests/Support/SpecialCaseListTest.cpp (+51-12) 


``````````diff
diff --git a/llvm/include/llvm/Support/SpecialCaseList.h b/llvm/include/llvm/Support/SpecialCaseList.h
index 64cad804ad911..d8dd1c4ec4bbc 100644
--- a/llvm/include/llvm/Support/SpecialCaseList.h
+++ b/llvm/include/llvm/Support/SpecialCaseList.h
@@ -156,6 +156,7 @@ class SpecialCaseList {
 
     std::vector<std::unique_ptr<Matcher::Glob>> Globs;
     std::vector<std::unique_ptr<Reg>> RegExes;
+    bool RemoveDotSlash = false;
   };
 
   using SectionEntries = StringMap<StringMap<Matcher>>;
diff --git a/llvm/lib/Support/SpecialCaseList.cpp b/llvm/lib/Support/SpecialCaseList.cpp
index 6ad8d7d4e7ffa..636dc5e651f56 100644
--- a/llvm/lib/Support/SpecialCaseList.cpp
+++ b/llvm/lib/Support/SpecialCaseList.cpp
@@ -22,6 +22,7 @@
 #include "llvm/Support/VirtualFileSystem.h"
 #include <algorithm>
 #include <limits>
+#include <memory>
 #include <stdio.h>
 #include <string>
 #include <system_error>
@@ -72,6 +73,8 @@ Error SpecialCaseList::Matcher::insert(StringRef Pattern, unsigned LineNumber,
 void SpecialCaseList::Matcher::match(
     StringRef Query,
     llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
+  if (RemoveDotSlash)
+    Query = llvm::sys::path::remove_leading_dotslash(Query);
   for (const auto &Glob : reverse(Globs))
     if (Glob->Pattern.match(Query))
       Cb(Glob->Name, Glob->LineNo);
@@ -164,12 +167,16 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB,
   // https://discourse.llvm.org/t/use-glob-instead-of-regex-for-specialcaselists/71666
   bool UseGlobs = Version > 1;
 
+  bool RemoveDotSlash = Version > 2;
+
   Section *CurrentSection;
   if (auto Err = addSection("*", FileIdx, 1).moveInto(CurrentSection)) {
     Error = toString(std::move(Err));
     return false;
   }
 
+  constexpr StringRef PathPrefixes[] = {"src", "!src", "mainfile", "source"};
+
   for (line_iterator LineIt(*MB, /*SkipBlanks=*/true, /*CommentMarker=*/'#');
        !LineIt.is_at_eof(); LineIt++) {
     unsigned LineNo = LineIt.line_number();
@@ -205,6 +212,8 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB,
 
     auto [Pattern, Category] = Postfix.split("=");
     auto &Entry = CurrentSection->Entries[Prefix][Category];
+    Entry.RemoveDotSlash =
+        RemoveDotSlash && llvm::is_contained(PathPrefixes, Prefix);
     if (auto Err = Entry.insert(Pattern, LineNo, UseGlobs)) {
       Error =
           (Twine("malformed ") + (UseGlobs ? "glob" : "regex") + " in line " +
diff --git a/llvm/unittests/Support/SpecialCaseListTest.cpp b/llvm/unittests/Support/SpecialCaseListTest.cpp
index 5be2b9e3a7a5d..df6ee78f0933e 100644
--- a/llvm/unittests/Support/SpecialCaseListTest.cpp
+++ b/llvm/unittests/Support/SpecialCaseListTest.cpp
@@ -22,33 +22,31 @@ namespace {
 
 class SpecialCaseListTest : public ::testing::Test {
 protected:
-  std::unique_ptr<SpecialCaseList> makeSpecialCaseList(StringRef List,
-                                                       std::string &Error,
-                                                       bool UseGlobs = true) {
+  std::unique_ptr<SpecialCaseList>
+  makeSpecialCaseList(StringRef List, std::string &Error, int Version = 0) {
     auto S = List.str();
-    if (!UseGlobs)
-      S = (Twine("#!special-case-list-v1\n") + S).str();
+    if (Version)
+      S = (Twine("#!special-case-list-v") + Twine(Version) + "\n" + S).str();
     std::unique_ptr<MemoryBuffer> MB = MemoryBuffer::getMemBuffer(S);
     return SpecialCaseList::create(MB.get(), Error);
   }
 
   std::unique_ptr<SpecialCaseList> makeSpecialCaseList(StringRef List,
-                                                       bool UseGlobs = true) {
+                                                       int Version = 0) {
     std::string Error;
-    auto SCL = makeSpecialCaseList(List, Error, UseGlobs);
+    auto SCL = makeSpecialCaseList(List, Error, Version);
     assert(SCL);
     assert(Error == "");
     return SCL;
   }
 
-  std::string makeSpecialCaseListFile(StringRef Contents,
-                                      bool UseGlobs = true) {
+  std::string makeSpecialCaseListFile(StringRef Contents, int Version = 0) {
     int FD;
     SmallString<64> Path;
     sys::fs::createTemporaryFile("SpecialCaseListTest", "temp", FD, Path);
     raw_fd_ostream OF(FD, true, true);
-    if (!UseGlobs)
-      OF << "#!special-case-list-v1\n";
+    if (Version)
+      OF << "#!special-case-list-v" << Version << "\n";
     OF << Contents;
     OF.close();
     return std::string(Path.str());
@@ -261,7 +259,7 @@ TEST_F(SpecialCaseListTest, Version1) {
                           "fun:foo.*\n"
                           "fun:abc|def\n"
                           "fun:b.r\n",
-                          /*UseGlobs=*/false);
+                          /*Version=*/1);
 
   EXPECT_TRUE(SCL->inSection("sect1", "fun", "fooz"));
   EXPECT_TRUE(SCL->inSection("sect2", "fun", "fooz"));
@@ -283,6 +281,47 @@ TEST_F(SpecialCaseListTest, Version1) {
   EXPECT_FALSE(SCL->inSection("sect3", "fun", "bar"));
 }
 
+TEST_F(SpecialCaseListTest, DotSlash) {
+  std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("[sect1]\n"
+                                                             "fun:./foo\n"
+                                                             "src:./bar\n"
+                                                             "[sect2]\n"
+                                                             "fun:foo\n"
+                                                             "src:bar\n");
+  EXPECT_TRUE(SCL->inSection("sect1", "fun", "./foo"));
+  EXPECT_FALSE(SCL->inSection("sect1", "fun", "foo"));
+
+  EXPECT_TRUE(SCL->inSection("sect1", "src", "./bar"));
+  EXPECT_FALSE(SCL->inSection("sect1", "src", "bar"));
+
+  EXPECT_FALSE(SCL->inSection("sect2", "fun", "./foo"));
+  EXPECT_TRUE(SCL->inSection("sect2", "fun", "foo"));
+
+  EXPECT_FALSE(SCL->inSection("sect2", "src", "./bar"));
+  EXPECT_TRUE(SCL->inSection("sect2", "src", "bar"));
+}
+
+TEST_F(SpecialCaseListTest, DotSlashV3) {
+  std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("[sect1]\n"
+                                                             "fun:./foo\n"
+                                                             "src:./bar\n"
+                                                             "[sect2]\n"
+                                                             "fun:foo\n"
+                                                             "src:bar\n",
+                                                             /*Version=*/3);
+  EXPECT_TRUE(SCL->inSection("sect1", "fun", "./foo"));
+  EXPECT_FALSE(SCL->inSection("sect1", "fun", "foo"));
+
+  EXPECT_FALSE(SCL->inSection("sect1", "src", "./bar"));
+  EXPECT_FALSE(SCL->inSection("sect1", "src", "bar"));
+
+  EXPECT_FALSE(SCL->inSection("sect2", "fun", "./foo"));
+  EXPECT_TRUE(SCL->inSection("sect2", "fun", "foo"));
+
+  EXPECT_TRUE(SCL->inSection("sect2", "src", "./bar"));
+  EXPECT_TRUE(SCL->inSection("sect2", "src", "bar"));
+}
+
 TEST_F(SpecialCaseListTest, Version2) {
   std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("[{sect1,sect2}]\n"
                                                              "fun:foo*\n"

``````````

</details>


https://github.com/llvm/llvm-project/pull/162437


More information about the llvm-commits mailing list