-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[SpecialCaseList] Remove ./ from file path #162437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SpecialCaseList] Remove ./ from file path #162437
Conversation
Created using spr 1.3.6
@llvm/pr-subscribers-llvm-support Author: Vitaly Buka (vitalybuka) ChangesThis extends approach used in WarningsSpecialCaseList SpecialCaseList will remove leading "./" from the Query Now affected prefixes are "src", "!src", "mainfile", "source". To avoid breaking users, this behavior is enabled for Full diff: https://github.com/llvm/llvm-project/pull/162437.diff 3 Files Affected:
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"
|
Created using spr 1.3.6
Added comments to clarify the purpose of PathPrefixes.
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".