76 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// An extension of SpecialCaseList to allowing querying sections by10// SanitizerMask.11//12//===----------------------------------------------------------------------===//13#include "clang/Basic/SanitizerSpecialCaseList.h"14#include "llvm/ADT/STLExtras.h"15 16using namespace clang;17 18std::unique_ptr<SanitizerSpecialCaseList>19SanitizerSpecialCaseList::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 31std::unique_ptr<SanitizerSpecialCaseList>32SanitizerSpecialCaseList::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(StringRef(Error));38}39 40void SanitizerSpecialCaseList::createSanitizerSections() {41 for (const auto &S : sections()) {42 SanitizerMask Mask;43 44#define SANITIZER(NAME, ID) \45 if (S.matchName(NAME)) \46 Mask |= SanitizerKind::ID;47#define SANITIZER_GROUP(NAME, ID, ALIAS) SANITIZER(NAME, ID)48 49#include "clang/Basic/Sanitizers.def"50#undef SANITIZER51#undef SANITIZER_GROUP52 53 SanitizerSections.emplace_back(Mask, S);54 }55}56 57bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask, StringRef Prefix,58 StringRef Query,59 StringRef Category) const {60 return inSectionBlame(Mask, Prefix, Query, Category) != NotFound;61}62 63std::pair<unsigned, unsigned>64SanitizerSpecialCaseList::inSectionBlame(SanitizerMask Mask, StringRef Prefix,65 StringRef Query,66 StringRef Category) const {67 for (const auto &S : llvm::reverse(SanitizerSections)) {68 if (S.Mask & Mask) {69 unsigned LineNum = S.S.getLastMatch(Prefix, Query, Category);70 if (LineNum > 0)71 return {S.S.fileIndex(), LineNum};72 }73 }74 return NotFound;75}76