1 | //===--- SanitizerSpecialCaseList.cpp - SCL for sanitizers ----------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // An extension of SpecialCaseList to allowing querying sections by |
10 | // SanitizerMask. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | #include "clang/Basic/SanitizerSpecialCaseList.h" |
14 | #include "llvm/ADT/STLExtras.h" |
15 | |
16 | using namespace clang; |
17 | |
18 | std::unique_ptr<SanitizerSpecialCaseList> |
19 | SanitizerSpecialCaseList::create(const std::vector<std::string> &Paths, |
20 | llvm::vfs::FileSystem &VFS, |
21 | std::string &Error) { |
22 | std::unique_ptr<clang::SanitizerSpecialCaseList> SSCL( |
23 | new SanitizerSpecialCaseList()); |
24 | if (SSCL->createInternal(Paths, VFS, Error)) { |
25 | SSCL->createSanitizerSections(); |
26 | return SSCL; |
27 | } |
28 | return nullptr; |
29 | } |
30 | |
31 | std::unique_ptr<SanitizerSpecialCaseList> |
32 | SanitizerSpecialCaseList::createOrDie(const std::vector<std::string> &Paths, |
33 | llvm::vfs::FileSystem &VFS) { |
34 | std::string Error; |
35 | if (auto SSCL = create(Paths, VFS, Error)) |
36 | return SSCL; |
37 | llvm::report_fatal_error(reason: StringRef(Error)); |
38 | } |
39 | |
40 | void SanitizerSpecialCaseList::createSanitizerSections() { |
41 | for (auto &S : Sections) { |
42 | SanitizerMask Mask; |
43 | |
44 | #define SANITIZER(NAME, ID) \ |
45 | if (S.SectionMatcher->match(NAME)) \ |
46 | Mask |= SanitizerKind::ID; |
47 | #define SANITIZER_GROUP(NAME, ID, ALIAS) SANITIZER(NAME, ID) |
48 | |
49 | #include "clang/Basic/Sanitizers.def" |
50 | #undef SANITIZER |
51 | #undef SANITIZER_GROUP |
52 | |
53 | SanitizerSections.emplace_back(args&: Mask, args&: S.Entries, args&: S.FileIdx); |
54 | } |
55 | } |
56 | |
57 | bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask, StringRef Prefix, |
58 | StringRef Query, |
59 | StringRef Category) const { |
60 | return inSectionBlame(Mask, Prefix, Query, Category) != NotFound; |
61 | } |
62 | |
63 | std::pair<unsigned, unsigned> |
64 | SanitizerSpecialCaseList::inSectionBlame(SanitizerMask Mask, StringRef Prefix, |
65 | StringRef Query, |
66 | StringRef Category) const { |
67 | for (const auto &S : llvm::reverse(C: SanitizerSections)) { |
68 | if (S.Mask & Mask) { |
69 | unsigned LineNum = |
70 | SpecialCaseList::inSectionBlame(Entries: S.Entries, Prefix, Query, Category); |
71 | if (LineNum > 0) |
72 | return {S.FileIdx, LineNum}; |
73 | } |
74 | } |
75 | return NotFound; |
76 | } |
77 | |