Files
clang-p2996/clang/lib/Basic/SanitizerSpecialCaseList.cpp
Qinkun Bao 45b874bc57 [UBSan] Support src:*=sanitize for multiple ignorelists. (#141640)
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`.
2025-05-28 11:12:53 -04:00

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;
}