See: https://github.com/llvm/llvm-project/issues/139128 and https://github.com/llvm/llvm-project/pull/140529 for the background. The introduction of these new tests (ubsan-src-ignorelist-category.test) `-fsanitize-ignorelist=%t/src.ignorelist -fsanitize-ignorelist=%t/src.ignorelist.contradict9` in this PR will not lead to failures in the previous implementation (without this PR). This is because the existing logic distinguishes between Sections in different ignorelists, even if their names are identical. The order of these Sections is preserved using a `vector`.
77 lines
2.7 KiB
C++
77 lines
2.7 KiB
C++
//===--- SanitizerSpecialCaseList.cpp - SCL for sanitizers ----------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// An extension of SpecialCaseList to allowing querying sections by
|
|
// SanitizerMask.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "clang/Basic/SanitizerSpecialCaseList.h"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
using namespace clang;
|
|
|
|
std::unique_ptr<SanitizerSpecialCaseList>
|
|
SanitizerSpecialCaseList::create(const std::vector<std::string> &Paths,
|
|
llvm::vfs::FileSystem &VFS,
|
|
std::string &Error) {
|
|
std::unique_ptr<clang::SanitizerSpecialCaseList> SSCL(
|
|
new SanitizerSpecialCaseList());
|
|
if (SSCL->createInternal(Paths, VFS, Error)) {
|
|
SSCL->createSanitizerSections();
|
|
return SSCL;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
std::unique_ptr<SanitizerSpecialCaseList>
|
|
SanitizerSpecialCaseList::createOrDie(const std::vector<std::string> &Paths,
|
|
llvm::vfs::FileSystem &VFS) {
|
|
std::string Error;
|
|
if (auto SSCL = create(Paths, VFS, Error))
|
|
return SSCL;
|
|
llvm::report_fatal_error(StringRef(Error));
|
|
}
|
|
|
|
void SanitizerSpecialCaseList::createSanitizerSections() {
|
|
for (auto &S : Sections) {
|
|
SanitizerMask Mask;
|
|
|
|
#define SANITIZER(NAME, ID) \
|
|
if (S.SectionMatcher->match(NAME)) \
|
|
Mask |= SanitizerKind::ID;
|
|
#define SANITIZER_GROUP(NAME, ID, ALIAS) SANITIZER(NAME, ID)
|
|
|
|
#include "clang/Basic/Sanitizers.def"
|
|
#undef SANITIZER
|
|
#undef SANITIZER_GROUP
|
|
|
|
SanitizerSections.emplace_back(Mask, S.Entries, S.FileIdx);
|
|
}
|
|
}
|
|
|
|
bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask, StringRef Prefix,
|
|
StringRef Query,
|
|
StringRef Category) const {
|
|
return inSectionBlame(Mask, Prefix, Query, Category) != NotFound;
|
|
}
|
|
|
|
std::pair<unsigned, unsigned>
|
|
SanitizerSpecialCaseList::inSectionBlame(SanitizerMask Mask, StringRef Prefix,
|
|
StringRef Query,
|
|
StringRef Category) const {
|
|
for (const auto &S : llvm::reverse(SanitizerSections)) {
|
|
if (S.Mask & Mask) {
|
|
unsigned LineNum =
|
|
SpecialCaseList::inSectionBlame(S.Entries, Prefix, Query, Category);
|
|
if (LineNum > 0)
|
|
return {S.FileIdx, LineNum};
|
|
}
|
|
}
|
|
return NotFound;
|
|
}
|