Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion clang/lib/Basic/Diagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,8 @@ std::unique_ptr<WarningsSpecialCaseList>
WarningsSpecialCaseList::create(const llvm::MemoryBuffer &Input,
std::string &Err) {
auto WarningSuppressionList = std::make_unique<WarningsSpecialCaseList>();
if (!WarningSuppressionList->createInternal(&Input, Err))
if (!WarningSuppressionList->createInternal(&Input, Err,
/*OrderBySize=*/true))
return nullptr;
return WarningSuppressionList;
}
Expand Down
47 changes: 30 additions & 17 deletions clang/unittests/Basic/DiagnosticTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "llvm/Support/VirtualFileSystem.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <algorithm>
#include <memory>
#include <optional>
#include <vector>
Expand Down Expand Up @@ -295,23 +296,35 @@ TEST_F(SuppressionMappingTest, EmitCategoryIsExcluded) {
}

TEST_F(SuppressionMappingTest, LongestMatchWins) {
llvm::StringLiteral SuppressionMappingFile = R"(
[unused]
src:*clang/*
src:*clang/lib/Sema/*=emit
src:*clang/lib/Sema/foo*)";
Diags.getDiagnosticOptions().DiagnosticSuppressionMappingsFile = "foo.txt";
FS->addFile("foo.txt", /*ModificationTime=*/{},
llvm::MemoryBuffer::getMemBuffer(SuppressionMappingFile));
clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS);
EXPECT_THAT(diags(), IsEmpty());

EXPECT_TRUE(Diags.isSuppressedViaMapping(
diag::warn_unused_function, locForFile("clang/lib/Basic/foo.h")));
EXPECT_FALSE(Diags.isSuppressedViaMapping(
diag::warn_unused_function, locForFile("clang/lib/Sema/bar.h")));
EXPECT_TRUE(Diags.isSuppressedViaMapping(diag::warn_unused_function,
locForFile("clang/lib/Sema/foo.h")));
StringRef Lines[] = {
"[unused]",
"src:*clang/*",
"src:*clang/lib/Sema/*",
"src:*clang/lib/Sema/*=emit",
"src:*clang/lib/Sema/foo*",
};
llvm::MutableArrayRef<StringRef> Rules = Lines;
Rules = Rules.drop_front();
llvm::sort(Rules);

do {
Diags.getDiagnosticOptions().DiagnosticSuppressionMappingsFile = "foo.txt";
std::string Contents = join(std::begin(Lines), std::end(Lines), "\n");
FS->addFile("foo.txt", /*ModificationTime=*/{},
llvm::MemoryBuffer::getMemBuffer(Contents));
clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS);
EXPECT_THAT(diags(), IsEmpty());

EXPECT_TRUE(Diags.isSuppressedViaMapping(
diag::warn_unused_function, locForFile("clang/lib/Basic/foo.h")))
<< Contents;
EXPECT_FALSE(Diags.isSuppressedViaMapping(
diag::warn_unused_function, locForFile("clang/lib/Sema/bar.h")))
<< Contents;
EXPECT_TRUE(Diags.isSuppressedViaMapping(
diag::warn_unused_function, locForFile("clang/lib/Sema/foo.h")))
<< Contents;
} while (std::next_permutation(Rules.begin(), Rules.end()));
}

TEST_F(SuppressionMappingTest, LongShortMatch) {
Expand Down
16 changes: 12 additions & 4 deletions llvm/include/llvm/Support/SpecialCaseList.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ class SpecialCaseList {
// classes.
LLVM_ABI bool createInternal(const std::vector<std::string> &Paths,
vfs::FileSystem &VFS, std::string &Error);
LLVM_ABI bool createInternal(const MemoryBuffer *MB, std::string &Error);
LLVM_ABI bool createInternal(const MemoryBuffer *MB, std::string &Error,
bool OrderBySize = false);

SpecialCaseList() = default;
SpecialCaseList(SpecialCaseList const &) = delete;
Expand All @@ -126,6 +127,8 @@ class SpecialCaseList {
class RegexMatcher {
public:
LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
LLVM_ABI void preprocess(bool BySize);

LLVM_ABI void
match(StringRef Query,
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
Expand All @@ -144,6 +147,8 @@ class SpecialCaseList {
class GlobMatcher {
public:
LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
LLVM_ABI void preprocess(bool BySize);

LLVM_ABI void
match(StringRef Query,
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
Expand All @@ -164,6 +169,9 @@ class SpecialCaseList {
public:
LLVM_ABI Matcher(bool UseGlobs, bool RemoveDotSlash);

LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
LLVM_ABI void preprocess(bool BySize);

LLVM_ABI void
match(StringRef Query,
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
Expand All @@ -174,8 +182,6 @@ class SpecialCaseList {
return R;
}

LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);

std::variant<RegexMatcher, GlobMatcher> M;
bool RemoveDotSlash;
};
Expand Down Expand Up @@ -206,6 +212,8 @@ class SpecialCaseList {
StringRef Category) const;

private:
friend class SpecialCaseList;
LLVM_ABI void preprocess(bool OrderBySize);
LLVM_ABI const SpecialCaseList::Matcher *
findMatcher(StringRef Prefix, StringRef Category) const;
};
Expand All @@ -222,7 +230,7 @@ class SpecialCaseList {

/// Parses just-constructed SpecialCaseList entries from a memory buffer.
LLVM_ABI bool parse(unsigned FileIdx, const MemoryBuffer *MB,
std::string &Error);
std::string &Error, bool OrderBySize);
};

} // namespace llvm
Expand Down
53 changes: 42 additions & 11 deletions llvm/lib/Support/SpecialCaseList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,20 @@ Error SpecialCaseList::RegexMatcher::insert(StringRef Pattern,
return Error::success();
}

void SpecialCaseList::RegexMatcher::preprocess(bool BySize) {
if (BySize) {
llvm::sort(RegExes, [](const Reg &A, const Reg &B) {
return A.Name.size() < B.Name.size();
});
}
}

void SpecialCaseList::RegexMatcher::match(
StringRef Query,
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
for (const auto &R : reverse(RegExes))
if (R.Rg.match(Query))
Cb(R.Name, R.LineNo);
return Cb(R.Name, R.LineNo);
}

Error SpecialCaseList::GlobMatcher::insert(StringRef Pattern,
Expand All @@ -75,12 +83,20 @@ Error SpecialCaseList::GlobMatcher::insert(StringRef Pattern,
return Error::success();
}

void SpecialCaseList::GlobMatcher::preprocess(bool BySize) {
if (BySize) {
llvm::sort(Globs, [](const Glob &A, const Glob &B) {
return A.Name.size() < B.Name.size();
});
}
}

void SpecialCaseList::GlobMatcher::match(
StringRef Query,
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
for (const auto &G : reverse(Globs))
if (G.Pattern.match(Query))
Cb(G.Name, G.LineNo);
return Cb(G.Name, G.LineNo);
}

SpecialCaseList::Matcher::Matcher(bool UseGlobs, bool RemoveDotSlash)
Expand All @@ -91,6 +107,14 @@ SpecialCaseList::Matcher::Matcher(bool UseGlobs, bool RemoveDotSlash)
M.emplace<RegexMatcher>();
}

Error SpecialCaseList::Matcher::insert(StringRef Pattern, unsigned LineNumber) {
return std::visit([&](auto &V) { return V.insert(Pattern, LineNumber); }, M);
}

LLVM_ABI void SpecialCaseList::Matcher::preprocess(bool BySize) {
return std::visit([&](auto &V) { return V.preprocess(BySize); }, M);
}

void SpecialCaseList::Matcher::match(
StringRef Query,
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
Expand All @@ -99,10 +123,6 @@ void SpecialCaseList::Matcher::match(
return std::visit([&](auto &V) { return V.match(Query, Cb); }, M);
}

Error SpecialCaseList::Matcher::insert(StringRef Pattern, unsigned LineNumber) {
return std::visit([&](auto &V) { return V.insert(Pattern, LineNumber); }, M);
}

// TODO: Refactor this to return Expected<...>
std::unique_ptr<SpecialCaseList>
SpecialCaseList::create(const std::vector<std::string> &Paths,
Expand Down Expand Up @@ -141,17 +161,17 @@ bool SpecialCaseList::createInternal(const std::vector<std::string> &Paths,
return false;
}
std::string ParseError;
if (!parse(i, FileOrErr.get().get(), ParseError)) {
if (!parse(i, FileOrErr.get().get(), ParseError, /*OrderBySize=*/false)) {
Error = (Twine("error parsing file '") + Path + "': " + ParseError).str();
return false;
}
}
return true;
}

bool SpecialCaseList::createInternal(const MemoryBuffer *MB,
std::string &Error) {
if (!parse(0, MB, Error))
bool SpecialCaseList::createInternal(const MemoryBuffer *MB, std::string &Error,
bool OrderBySize) {
if (!parse(0, MB, Error, OrderBySize))
return false;
return true;
}
Expand All @@ -174,7 +194,7 @@ SpecialCaseList::addSection(StringRef SectionStr, unsigned FileNo,
}

bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB,
std::string &Error) {
std::string &Error, bool OrderBySize) {
unsigned long long Version = 2;

StringRef Header = MB->getBuffer();
Expand Down Expand Up @@ -246,6 +266,10 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB,
return false;
}
}

for (Section &S : Sections)
S.preprocess(OrderBySize);

return true;
}

Expand Down Expand Up @@ -283,6 +307,13 @@ SpecialCaseList::Section::findMatcher(StringRef Prefix,
return &II->second;
}

LLVM_ABI void SpecialCaseList::Section::preprocess(bool OrderBySize) {
SectionMatcher.preprocess(false);
for (auto &[K1, E] : Entries)
for (auto &[K2, M] : E)
M.preprocess(OrderBySize);
}

unsigned SpecialCaseList::Section::getLastMatch(StringRef Prefix,
StringRef Query,
StringRef Category) const {
Expand Down
Loading