[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