summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Support/SpecialCaseList.h76
-rw-r--r--llvm/lib/Support/SpecialCaseList.cpp214
-rw-r--r--llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp11
-rw-r--r--llvm/tools/llvm-cov/CoverageFilters.cpp2
-rw-r--r--llvm/tools/sancov/sancov.cc11
-rw-r--r--llvm/unittests/Support/SpecialCaseListTest.cpp138
6 files changed, 296 insertions, 156 deletions
diff --git a/llvm/include/llvm/Support/SpecialCaseList.h b/llvm/include/llvm/Support/SpecialCaseList.h
index ce693c50131..f76ca305efb 100644
--- a/llvm/include/llvm/Support/SpecialCaseList.h
+++ b/llvm/include/llvm/Support/SpecialCaseList.h
@@ -8,15 +8,19 @@
//
// This is a utility class used to parse user-provided text files with
// "special case lists" for code sanitizers. Such files are used to
-// define "ABI list" for DataFlowSanitizer and blacklists for another sanitizers
+// define an "ABI list" for DataFlowSanitizer and blacklists for sanitizers
// like AddressSanitizer or UndefinedBehaviorSanitizer.
//
-// Empty lines and lines starting with "#" are ignored. All the rest lines
-// should have the form:
-// section:wildcard_expression[=category]
+// Empty lines and lines starting with "#" are ignored. Sections are defined
+// using a '[section_name]' header and can be used to specify sanitizers the
+// entries below it apply to. Section names are regular expressions, and
+// entries without a section header match all sections (e.g. an '[*]' header
+// is assumed.)
+// The remaining lines should have the form:
+// prefix:wildcard_expression[=category]
// If category is not specified, it is assumed to be empty string.
-// Definitions of "section" and "category" are sanitizer-specific. For example,
-// sanitizer blacklists support sections "src", "fun" and "global".
+// Definitions of "prefix" and "category" are sanitizer-specific. For example,
+// sanitizer blacklists support prefixes "src", "fun" and "global".
// Wildcard expressions define, respectively, source files, functions or
// globals which shouldn't be instrumented.
// Examples of categories:
@@ -26,6 +30,7 @@
// detection for certain globals or source files.
// Full special case list file example:
// ---
+// [address]
// # Blacklisted items:
// fun:*_ZN4base6subtle*
// global:*global_with_bad_access_or_initialization*
@@ -34,14 +39,13 @@
// src:file_with_tricky_code.cc
// src:ignore-global-initializers-issues.cc=init
//
+// [dataflow]
// # Functions with pure functional semantics:
// fun:cos=functional
// fun:sin=functional
// ---
// Note that the wild card is in fact an llvm::Regex, but * is automatically
// replaced with .*
-// This is similar to the "ignore" feature of ThreadSanitizer.
-// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores
//
//===----------------------------------------------------------------------===//
@@ -49,6 +53,9 @@
#define LLVM_SUPPORT_SPECIALCASELIST_H
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/TrigramIndex.h"
#include <string>
#include <vector>
@@ -76,26 +83,63 @@ public:
/// Returns true, if special case list contains a line
/// \code
- /// @Section:<E>=@Category
+ /// @Prefix:<E>=@Category
/// \endcode
- /// and @Query satisfies a wildcard expression <E>.
- bool inSection(StringRef Section, StringRef Query,
+ /// where @Query satisfies wildcard expression <E> in a given @Section.
+ bool inSection(StringRef Section, StringRef Prefix, StringRef Query,
StringRef Category = StringRef()) const;
-private:
+protected:
+ // Implementations of the create*() functions that can also be used by derived
+ // classes.
+ bool createInternal(const std::vector<std::string> &Paths,
+ std::string &Error);
+ bool createInternal(const MemoryBuffer *MB, std::string &Error);
+
SpecialCaseList(SpecialCaseList const &) = delete;
SpecialCaseList &operator=(SpecialCaseList const &) = delete;
- struct Entry;
- StringMap<StringMap<Entry>> Entries;
- StringMap<StringMap<std::string>> Regexps;
+ /// Represents a set of regular expressions. Regular expressions which are
+ /// "literal" (i.e. no regex metacharacters) are stored in Strings, while all
+ /// others are represented as a single pipe-separated regex in RegEx. The
+ /// reason for doing so is efficiency; StringSet is much faster at matching
+ /// literal strings than Regex.
+ class Matcher {
+ public:
+ bool insert(std::string Regexp, std::string &REError);
+ void compile();
+ bool match(StringRef Query) const;
+
+ private:
+ StringSet<> Strings;
+ TrigramIndex Trigrams;
+ std::unique_ptr<Regex> RegEx;
+ std::string UncompiledRegEx;
+ };
+
+ using SectionEntries = StringMap<StringMap<Matcher>>;
+
+ struct Section {
+ Section(std::unique_ptr<Matcher> M) : SectionMatcher(std::move(M)){};
+
+ std::unique_ptr<Matcher> SectionMatcher;
+ SectionEntries Entries;
+ };
+
+ std::vector<Section> Sections;
bool IsCompiled;
SpecialCaseList();
/// Parses just-constructed SpecialCaseList entries from a memory buffer.
- bool parse(const MemoryBuffer *MB, std::string &Error);
+ bool parse(const MemoryBuffer *MB, StringMap<size_t> &SectionsMap,
+ std::string &Error);
/// compile() should be called once, after parsing all the memory buffers.
void compile();
+
+ // Helper method for derived classes to search by Prefix, Query, and Category
+ // once they have already resolved a section entry.
+ bool inSection(const SectionEntries &Entries, StringRef Prefix,
+ StringRef Query, StringRef Category) const;
};
} // namespace llvm
diff --git a/llvm/lib/Support/SpecialCaseList.cpp b/llvm/lib/Support/SpecialCaseList.cpp
index 05886eaa8ae..25222b04119 100644
--- a/llvm/lib/Support/SpecialCaseList.cpp
+++ b/llvm/lib/Support/SpecialCaseList.cpp
@@ -17,65 +17,72 @@
#include "llvm/Support/SpecialCaseList.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringSet.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Regex.h"
-#include "llvm/Support/TrigramIndex.h"
#include <string>
#include <system_error>
#include <utility>
+#include <stdio.h>
namespace llvm {
-/// Represents a set of regular expressions. Regular expressions which are
-/// "literal" (i.e. no regex metacharacters) are stored in Strings, while all
-/// others are represented as a single pipe-separated regex in RegEx. The
-/// reason for doing so is efficiency; StringSet is much faster at matching
-/// literal strings than Regex.
-struct SpecialCaseList::Entry {
- StringSet<> Strings;
- TrigramIndex Trigrams;
- std::unique_ptr<Regex> RegEx;
-
- bool match(StringRef Query) const {
- if (Strings.count(Query))
- return true;
- if (Trigrams.isDefinitelyOut(Query))
- return false;
- return RegEx && RegEx->match(Query);
+bool SpecialCaseList::Matcher::insert(std::string Regexp,
+ std::string &REError) {
+ if (Regex::isLiteralERE(Regexp)) {
+ Strings.insert(Regexp);
+ return true;
+ }
+ Trigrams.insert(Regexp);
+
+ // Replace * with .*
+ for (size_t pos = 0; (pos = Regexp.find('*', pos)) != std::string::npos;
+ pos += strlen(".*")) {
+ Regexp.replace(pos, strlen("*"), ".*");
+ }
+
+ // Check that the regexp is valid.
+ Regex CheckRE(Regexp);
+ if (!CheckRE.isValid(REError))
+ return false;
+
+ if (!UncompiledRegEx.empty())
+ UncompiledRegEx += "|";
+ UncompiledRegEx += "^(" + Regexp + ")$";
+ return true;
+}
+
+void SpecialCaseList::Matcher::compile() {
+ if (!UncompiledRegEx.empty()) {
+ RegEx.reset(new Regex(UncompiledRegEx));
+ UncompiledRegEx.clear();
}
-};
+}
+
+bool SpecialCaseList::Matcher::match(StringRef Query) const {
+ if (Strings.count(Query))
+ return true;
+ if (Trigrams.isDefinitelyOut(Query))
+ return false;
+ return RegEx && RegEx->match(Query);
+}
-SpecialCaseList::SpecialCaseList() : Entries(), Regexps(), IsCompiled(false) {}
+SpecialCaseList::SpecialCaseList() : Sections(), IsCompiled(false) {}
std::unique_ptr<SpecialCaseList>
SpecialCaseList::create(const std::vector<std::string> &Paths,
std::string &Error) {
std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList());
- for (const auto &Path : Paths) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
- MemoryBuffer::getFile(Path);
- if (std::error_code EC = FileOrErr.getError()) {
- Error = (Twine("can't open file '") + Path + "': " + EC.message()).str();
- return nullptr;
- }
- std::string ParseError;
- if (!SCL->parse(FileOrErr.get().get(), ParseError)) {
- Error = (Twine("error parsing file '") + Path + "': " + ParseError).str();
- return nullptr;
- }
- }
- SCL->compile();
- return SCL;
+ if (SCL->createInternal(Paths, Error))
+ return SCL;
+ return nullptr;
}
std::unique_ptr<SpecialCaseList> SpecialCaseList::create(const MemoryBuffer *MB,
std::string &Error) {
std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList());
- if (!SCL->parse(MB, Error))
- return nullptr;
- SCL->compile();
- return SCL;
+ if (SCL->createInternal(MB, Error))
+ return SCL;
+ return nullptr;
}
std::unique_ptr<SpecialCaseList>
@@ -86,15 +93,71 @@ SpecialCaseList::createOrDie(const std::vector<std::string> &Paths) {
report_fatal_error(Error);
}
-bool SpecialCaseList::parse(const MemoryBuffer *MB, std::string &Error) {
+bool SpecialCaseList::createInternal(const std::vector<std::string> &Paths,
+ std::string &Error) {
+ StringMap<size_t> Sections;
+ for (const auto &Path : Paths) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
+ MemoryBuffer::getFile(Path);
+ if (std::error_code EC = FileOrErr.getError()) {
+ Error = (Twine("can't open file '") + Path + "': " + EC.message()).str();
+ return false;
+ }
+ std::string ParseError;
+ if (!parse(FileOrErr.get().get(), Sections, ParseError)) {
+ Error = (Twine("error parsing file '") + Path + "': " + ParseError).str();
+ return false;
+ }
+ }
+ compile();
+ return true;
+}
+
+bool SpecialCaseList::createInternal(const MemoryBuffer *MB,
+ std::string &Error) {
+ StringMap<size_t> Sections;
+ if (!parse(MB, Sections, Error))
+ return false;
+ compile();
+ return true;
+}
+
+bool SpecialCaseList::parse(const MemoryBuffer *MB,
+ StringMap<size_t> &SectionsMap,
+ std::string &Error) {
// Iterate through each line in the blacklist file.
SmallVector<StringRef, 16> Lines;
SplitString(MB->getBuffer(), Lines, "\n\r");
+
int LineNo = 1;
+ StringRef Section = "*";
for (auto I = Lines.begin(), E = Lines.end(); I != E; ++I, ++LineNo) {
// Ignore empty lines and lines starting with "#"
if (I->empty() || I->startswith("#"))
continue;
+
+ // Save section names
+ if (I->startswith("[")) {
+ if (!I->endswith("]")) {
+ Error = (Twine("malformed section header on line ") + Twine(LineNo) +
+ ": " + *I).str();
+ return false;
+ }
+
+ Section = I->slice(1, I->size() - 1);
+
+ std::string REError;
+ Regex CheckRE(Section);
+ if (!CheckRE.isValid(REError)) {
+ Error =
+ (Twine("malformed regex for section ") + Section + ": '" + REError)
+ .str();
+ return false;
+ }
+
+ continue;
+ }
+
// Get our prefix and unparsed regexp.
std::pair<StringRef, StringRef> SplitLine = I->split(":");
StringRef Prefix = SplitLine.first;
@@ -109,61 +172,62 @@ bool SpecialCaseList::parse(const MemoryBuffer *MB, std::string &Error) {
std::string Regexp = SplitRegexp.first;
StringRef Category = SplitRegexp.second;
- // See if we can store Regexp in Strings.
- auto &Entry = Entries[Prefix][Category];
- if (Regex::isLiteralERE(Regexp)) {
- Entry.Strings.insert(Regexp);
- continue;
- }
- Entry.Trigrams.insert(Regexp);
-
- // Replace * with .*
- for (size_t pos = 0; (pos = Regexp.find('*', pos)) != std::string::npos;
- pos += strlen(".*")) {
- Regexp.replace(pos, strlen("*"), ".*");
+ // Create this section if it has not been seen before.
+ if (SectionsMap.find(Section) == SectionsMap.end()) {
+ std::unique_ptr<Matcher> M = make_unique<Matcher>();
+ std::string REError;
+ if (!M->insert(Section, REError)) {
+ Error = (Twine("malformed section ") + Section + ": '" + REError).str();
+ return false;
+ }
+ M->compile();
+
+ SectionsMap[Section] = Sections.size();
+ Sections.emplace_back(std::move(M));
}
- // Check that the regexp is valid.
- Regex CheckRE(Regexp);
+ auto &Entry = Sections[SectionsMap[Section]].Entries[Prefix][Category];
std::string REError;
- if (!CheckRE.isValid(REError)) {
+ if (!Entry.insert(std::move(Regexp), REError)) {
Error = (Twine("malformed regex in line ") + Twine(LineNo) + ": '" +
SplitLine.second + "': " + REError).str();
return false;
}
-
- // Add this regexp into the proper group by its prefix.
- if (!Regexps[Prefix][Category].empty())
- Regexps[Prefix][Category] += "|";
- Regexps[Prefix][Category] += "^" + Regexp + "$";
}
return true;
}
void SpecialCaseList::compile() {
assert(!IsCompiled && "compile() should only be called once");
- // Iterate through each of the prefixes, and create Regexs for them.
- for (StringMap<StringMap<std::string>>::const_iterator I = Regexps.begin(),
- E = Regexps.end();
- I != E; ++I) {
- for (StringMap<std::string>::const_iterator II = I->second.begin(),
- IE = I->second.end();
- II != IE; ++II) {
- Entries[I->getKey()][II->getKey()].RegEx.reset(new Regex(II->getValue()));
- }
- }
- Regexps.clear();
+ // Iterate through every section compiling regular expressions for every query
+ // and creating Section entries.
+ for (auto &Section : Sections)
+ for (auto &Prefix : Section.Entries)
+ for (auto &Category : Prefix.getValue())
+ Category.getValue().compile();
+
IsCompiled = true;
}
SpecialCaseList::~SpecialCaseList() {}
-bool SpecialCaseList::inSection(StringRef Section, StringRef Query,
- StringRef Category) const {
+bool SpecialCaseList::inSection(StringRef Section, StringRef Prefix,
+ StringRef Query, StringRef Category) const {
assert(IsCompiled && "SpecialCaseList::compile() was not called!");
- StringMap<StringMap<Entry> >::const_iterator I = Entries.find(Section);
+
+ for (auto &SectionIter : Sections)
+ if (SectionIter.SectionMatcher->match(Section) &&
+ inSection(SectionIter.Entries, Prefix, Query, Category))
+ return true;
+
+ return false;
+}
+
+bool SpecialCaseList::inSection(const SectionEntries &Entries, StringRef Prefix,
+ StringRef Query, StringRef Category) const {
+ SectionEntries::const_iterator I = Entries.find(Prefix);
if (I == Entries.end()) return false;
- StringMap<Entry>::const_iterator II = I->second.find(Category);
+ StringMap<Matcher>::const_iterator II = I->second.find(Category);
if (II == I->second.end()) return false;
return II->getValue().match(Query);
diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index ddc975cbed1..d74ccdfccb8 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -155,7 +155,7 @@ class DFSanABIList {
/// given category.
bool isIn(const Function &F, StringRef Category) const {
return isIn(*F.getParent(), Category) ||
- SCL->inSection("fun", F.getName(), Category);
+ SCL->inSection("dataflow", "fun", F.getName(), Category);
}
/// Returns whether this global alias is listed in the given category.
@@ -167,15 +167,16 @@ class DFSanABIList {
return true;
if (isa<FunctionType>(GA.getValueType()))
- return SCL->inSection("fun", GA.getName(), Category);
+ return SCL->inSection("dataflow", "fun", GA.getName(), Category);
- return SCL->inSection("global", GA.getName(), Category) ||
- SCL->inSection("type", GetGlobalTypeString(GA), Category);
+ return SCL->inSection("dataflow", "global", GA.getName(), Category) ||
+ SCL->inSection("dataflow", "type", GetGlobalTypeString(GA),
+ Category);
}
/// Returns whether this module is listed in the given category.
bool isIn(const Module &M, StringRef Category) const {
- return SCL->inSection("src", M.getModuleIdentifier(), Category);
+ return SCL->inSection("dataflow", "src", M.getModuleIdentifier(), Category);
}
};
diff --git a/llvm/tools/llvm-cov/CoverageFilters.cpp b/llvm/tools/llvm-cov/CoverageFilters.cpp
index 0ed9b2c899a..ce78bb2713c 100644
--- a/llvm/tools/llvm-cov/CoverageFilters.cpp
+++ b/llvm/tools/llvm-cov/CoverageFilters.cpp
@@ -32,7 +32,7 @@ bool NameRegexCoverageFilter::matches(
bool NameWhitelistCoverageFilter::matches(
const coverage::CoverageMapping &,
const coverage::FunctionRecord &Function) {
- return Whitelist.inSection("whitelist_fun", Function.Name);
+ return Whitelist.inSection("llvmcov", "whitelist_fun", Function.Name);
}
bool RegionCoverageFilter::matches(const coverage::CoverageMapping &CM,
diff --git a/llvm/tools/sancov/sancov.cc b/llvm/tools/sancov/sancov.cc
index 7f103ebb904..4a4c00f27ad 100644
--- a/llvm/tools/sancov/sancov.cc
+++ b/llvm/tools/sancov/sancov.cc
@@ -584,13 +584,16 @@ public:
UserBlacklist(createUserBlacklist()) {}
bool isBlacklisted(const DILineInfo &I) {
- if (DefaultBlacklist && DefaultBlacklist->inSection("fun", I.FunctionName))
+ if (DefaultBlacklist &&
+ DefaultBlacklist->inSection("sancov", "fun", I.FunctionName))
return true;
- if (DefaultBlacklist && DefaultBlacklist->inSection("src", I.FileName))
+ if (DefaultBlacklist &&
+ DefaultBlacklist->inSection("sancov", "src", I.FileName))
return true;
- if (UserBlacklist && UserBlacklist->inSection("fun", I.FunctionName))
+ if (UserBlacklist &&
+ UserBlacklist->inSection("sancov", "fun", I.FunctionName))
return true;
- if (UserBlacklist && UserBlacklist->inSection("src", I.FileName))
+ if (UserBlacklist && UserBlacklist->inSection("sancov", "src", I.FileName))
return true;
return false;
}
diff --git a/llvm/unittests/Support/SpecialCaseListTest.cpp b/llvm/unittests/Support/SpecialCaseListTest.cpp
index 130848845e4..0aa8452c0dd 100644
--- a/llvm/unittests/Support/SpecialCaseListTest.cpp
+++ b/llvm/unittests/Support/SpecialCaseListTest.cpp
@@ -51,47 +51,75 @@ TEST_F(SpecialCaseListTest, Basic) {
"src:bye\n"
"src:hi=category\n"
"src:z*=category\n");
- EXPECT_TRUE(SCL->inSection("src", "hello"));
- EXPECT_TRUE(SCL->inSection("src", "bye"));
- EXPECT_TRUE(SCL->inSection("src", "hi", "category"));
- EXPECT_TRUE(SCL->inSection("src", "zzzz", "category"));
- EXPECT_FALSE(SCL->inSection("src", "hi"));
- EXPECT_FALSE(SCL->inSection("fun", "hello"));
- EXPECT_FALSE(SCL->inSection("src", "hello", "category"));
+ EXPECT_TRUE(SCL->inSection("", "src", "hello"));
+ EXPECT_TRUE(SCL->inSection("", "src", "bye"));
+ EXPECT_TRUE(SCL->inSection("", "src", "hi", "category"));
+ EXPECT_TRUE(SCL->inSection("", "src", "zzzz", "category"));
+ EXPECT_FALSE(SCL->inSection("", "src", "hi"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "hello"));
+ EXPECT_FALSE(SCL->inSection("", "src", "hello", "category"));
+}
+
+TEST_F(SpecialCaseListTest, SectionRegexErrorHandling) {
+ std::string Error;
+ EXPECT_EQ(makeSpecialCaseList("[address", Error), nullptr);
+ EXPECT_TRUE(((StringRef)Error).startswith("malformed section header "));
+
+ EXPECT_EQ(makeSpecialCaseList("[[]", Error), nullptr);
+ EXPECT_TRUE(((StringRef)Error).startswith("malformed regex for section [: "));
+}
+
+TEST_F(SpecialCaseListTest, Section) {
+ std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:global\n"
+ "[sect1|sect2]\n"
+ "src:test1\n"
+ "[sect3*]\n"
+ "src:test2\n");
+ EXPECT_TRUE(SCL->inSection("arbitrary", "src", "global"));
+ EXPECT_TRUE(SCL->inSection("", "src", "global"));
+ EXPECT_TRUE(SCL->inSection("sect1", "src", "test1"));
+ EXPECT_FALSE(SCL->inSection("sect1-arbitrary", "src", "test1"));
+ EXPECT_FALSE(SCL->inSection("sect", "src", "test1"));
+ EXPECT_FALSE(SCL->inSection("sect1", "src", "test2"));
+ EXPECT_TRUE(SCL->inSection("sect2", "src", "test1"));
+ EXPECT_TRUE(SCL->inSection("sect3", "src", "test2"));
+ EXPECT_TRUE(SCL->inSection("sect3-arbitrary", "src", "test2"));
+ EXPECT_FALSE(SCL->inSection("", "src", "test1"));
+ EXPECT_FALSE(SCL->inSection("", "src", "test2"));
}
TEST_F(SpecialCaseListTest, GlobalInit) {
std::unique_ptr<SpecialCaseList> SCL =
makeSpecialCaseList("global:foo=init\n");
- EXPECT_FALSE(SCL->inSection("global", "foo"));
- EXPECT_FALSE(SCL->inSection("global", "bar"));
- EXPECT_TRUE(SCL->inSection("global", "foo", "init"));
- EXPECT_FALSE(SCL->inSection("global", "bar", "init"));
+ EXPECT_FALSE(SCL->inSection("", "global", "foo"));
+ EXPECT_FALSE(SCL->inSection("", "global", "bar"));
+ EXPECT_TRUE(SCL->inSection("", "global", "foo", "init"));
+ EXPECT_FALSE(SCL->inSection("", "global", "bar", "init"));
SCL = makeSpecialCaseList("type:t2=init\n");
- EXPECT_FALSE(SCL->inSection("type", "t1"));
- EXPECT_FALSE(SCL->inSection("type", "t2"));
- EXPECT_FALSE(SCL->inSection("type", "t1", "init"));
- EXPECT_TRUE(SCL->inSection("type", "t2", "init"));
+ EXPECT_FALSE(SCL->inSection("", "type", "t1"));
+ EXPECT_FALSE(SCL->inSection("", "type", "t2"));
+ EXPECT_FALSE(SCL->inSection("", "type", "t1", "init"));
+ EXPECT_TRUE(SCL->inSection("", "type", "t2", "init"));
SCL = makeSpecialCaseList("src:hello=init\n");
- EXPECT_FALSE(SCL->inSection("src", "hello"));
- EXPECT_FALSE(SCL->inSection("src", "bye"));
- EXPECT_TRUE(SCL->inSection("src", "hello", "init"));
- EXPECT_FALSE(SCL->inSection("src", "bye", "init"));
+ EXPECT_FALSE(SCL->inSection("", "src", "hello"));
+ EXPECT_FALSE(SCL->inSection("", "src", "bye"));
+ EXPECT_TRUE(SCL->inSection("", "src", "hello", "init"));
+ EXPECT_FALSE(SCL->inSection("", "src", "bye", "init"));
}
TEST_F(SpecialCaseListTest, Substring) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:hello\n"
"fun:foo\n"
"global:bar\n");
- EXPECT_FALSE(SCL->inSection("src", "othello"));
- EXPECT_FALSE(SCL->inSection("fun", "tomfoolery"));
- EXPECT_FALSE(SCL->inSection("global", "bartender"));
+ EXPECT_FALSE(SCL->inSection("", "src", "othello"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "tomfoolery"));
+ EXPECT_FALSE(SCL->inSection("", "global", "bartender"));
SCL = makeSpecialCaseList("fun:*foo*\n");
- EXPECT_TRUE(SCL->inSection("fun", "tomfoolery"));
- EXPECT_TRUE(SCL->inSection("fun", "foobar"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "tomfoolery"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "foobar"));
}
TEST_F(SpecialCaseListTest, InvalidSpecialCaseList) {
@@ -113,7 +141,7 @@ TEST_F(SpecialCaseListTest, InvalidSpecialCaseList) {
TEST_F(SpecialCaseListTest, EmptySpecialCaseList) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("");
- EXPECT_FALSE(SCL->inSection("foo", "bar"));
+ EXPECT_FALSE(SCL->inSection("", "foo", "bar"));
}
TEST_F(SpecialCaseListTest, MultipleBlacklists) {
@@ -124,12 +152,12 @@ TEST_F(SpecialCaseListTest, MultipleBlacklists) {
Files.push_back(makeSpecialCaseListFile("src:baz\n"
"src:*fog*\n"));
auto SCL = SpecialCaseList::createOrDie(Files);
- EXPECT_TRUE(SCL->inSection("src", "bar"));
- EXPECT_TRUE(SCL->inSection("src", "baz"));
- EXPECT_FALSE(SCL->inSection("src", "ban"));
- EXPECT_TRUE(SCL->inSection("src", "ban", "init"));
- EXPECT_TRUE(SCL->inSection("src", "tomfoolery"));
- EXPECT_TRUE(SCL->inSection("src", "tomfoglery"));
+ EXPECT_TRUE(SCL->inSection("", "src", "bar"));
+ EXPECT_TRUE(SCL->inSection("", "src", "baz"));
+ EXPECT_FALSE(SCL->inSection("", "src", "ban"));
+ EXPECT_TRUE(SCL->inSection("", "src", "ban", "init"));
+ EXPECT_TRUE(SCL->inSection("", "src", "tomfoolery"));
+ EXPECT_TRUE(SCL->inSection("", "src", "tomfoglery"));
for (auto &Path : Files)
sys::fs::remove(Path);
}
@@ -137,35 +165,35 @@ TEST_F(SpecialCaseListTest, MultipleBlacklists) {
TEST_F(SpecialCaseListTest, NoTrigramsInRules) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("fun:b.r\n"
"fun:za*az\n");
- EXPECT_TRUE(SCL->inSection("fun", "bar"));
- EXPECT_FALSE(SCL->inSection("fun", "baz"));
- EXPECT_TRUE(SCL->inSection("fun", "zakaz"));
- EXPECT_FALSE(SCL->inSection("fun", "zaraza"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "bar"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "baz"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "zakaz"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "zaraza"));
}
TEST_F(SpecialCaseListTest, NoTrigramsInARule) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("fun:*bar*\n"
"fun:za*az\n");
- EXPECT_TRUE(SCL->inSection("fun", "abara"));
- EXPECT_FALSE(SCL->inSection("fun", "bor"));
- EXPECT_TRUE(SCL->inSection("fun", "zakaz"));
- EXPECT_FALSE(SCL->inSection("fun", "zaraza"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "abara"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "bor"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "zakaz"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "zaraza"));
}
TEST_F(SpecialCaseListTest, RepetitiveRule) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("fun:*bar*bar*bar*bar*\n"
"fun:bar*\n");
- EXPECT_TRUE(SCL->inSection("fun", "bara"));
- EXPECT_FALSE(SCL->inSection("fun", "abara"));
- EXPECT_TRUE(SCL->inSection("fun", "barbarbarbar"));
- EXPECT_TRUE(SCL->inSection("fun", "abarbarbarbar"));
- EXPECT_FALSE(SCL->inSection("fun", "abarbarbar"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "bara"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "abara"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "barbarbarbar"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "abarbarbarbar"));
+ EXPECT_FALSE(SCL->inSection("", "fun", "abarbarbar"));
}
TEST_F(SpecialCaseListTest, SpecialSymbolRule) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:*c\\+\\+abi*\n");
- EXPECT_TRUE(SCL->inSection("src", "c++abi"));
- EXPECT_FALSE(SCL->inSection("src", "c\\+\\+abi"));
+ EXPECT_TRUE(SCL->inSection("", "src", "c++abi"));
+ EXPECT_FALSE(SCL->inSection("", "src", "c\\+\\+abi"));
}
TEST_F(SpecialCaseListTest, PopularTrigram) {
@@ -173,20 +201,20 @@ TEST_F(SpecialCaseListTest, PopularTrigram) {
"fun:*aaaaa*\n"
"fun:*aaaa*\n"
"fun:*aaa*\n");
- EXPECT_TRUE(SCL->inSection("fun", "aaa"));
- EXPECT_TRUE(SCL->inSection("fun", "aaaa"));
- EXPECT_TRUE(SCL->inSection("fun", "aaaabbbaaa"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "aaa"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "aaaa"));
+ EXPECT_TRUE(SCL->inSection("", "fun", "aaaabbbaaa"));
}
TEST_F(SpecialCaseListTest, EscapedSymbols) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:*c\\+\\+abi*\n"
"src:*hello\\\\world*\n");
- EXPECT_TRUE(SCL->inSection("src", "dir/c++abi"));
- EXPECT_FALSE(SCL->inSection("src", "dir/c\\+\\+abi"));
- EXPECT_FALSE(SCL->inSection("src", "c\\+\\+abi"));
- EXPECT_TRUE(SCL->inSection("src", "C:\\hello\\world"));
- EXPECT_TRUE(SCL->inSection("src", "hello\\world"));
- EXPECT_FALSE(SCL->inSection("src", "hello\\\\world"));
+ EXPECT_TRUE(SCL->inSection("", "src", "dir/c++abi"));
+ EXPECT_FALSE(SCL->inSection("", "src", "dir/c\\+\\+abi"));
+ EXPECT_FALSE(SCL->inSection("", "src", "c\\+\\+abi"));
+ EXPECT_TRUE(SCL->inSection("", "src", "C:\\hello\\world"));
+ EXPECT_TRUE(SCL->inSection("", "src", "hello\\world"));
+ EXPECT_FALSE(SCL->inSection("", "src", "hello\\\\world"));
}
}
OpenPOWER on IntegriCloud