vlad.tsyrklevich created this revision.
Herald added a subscriber: mgorny.

This is the follow-up patch to https://reviews.llvm.org/D37924.

This change refactors clang to use the the newly added section headers
in SpecialCaseList to specify which sanitizers blacklists entries
should apply to, like so:

  [cfi-vcall]
  fun:*bad_vcall*
  [cfi-derived-cast|cfi-unrelated-cast]
  fun:*bad_cast*

The SanitizerSpecialCaseList class has been added to allow querying by
SanitizerMask, and SanitizerBlacklist and its downstream users have been
updated to provide that information. Old blacklists not using sections
will continue to function identically since the blacklist entries will
be placed into a '[*]' section by default matching against all
sanitizers.


https://reviews.llvm.org/D37925

Files:
  include/clang/Basic/SanitizerBlacklist.h
  include/clang/Basic/SanitizerSpecialCaseList.h
  lib/AST/Decl.cpp
  lib/Basic/CMakeLists.txt
  lib/Basic/SanitizerBlacklist.cpp
  lib/Basic/SanitizerSpecialCaseList.cpp
  lib/Basic/XRayLists.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CGDeclCXX.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/CodeGenModule.h
  test/CodeGen/sanitizer-special-case-list.c
  test/CodeGenCXX/cfi-blacklist.cpp

Index: test/CodeGenCXX/cfi-blacklist.cpp
===================================================================
--- test/CodeGenCXX/cfi-blacklist.cpp
+++ test/CodeGenCXX/cfi-blacklist.cpp
@@ -1,6 +1,18 @@
 // RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOBL %s
-// RUN: echo "type:std::*" > %t.txt
-// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+
+// Check that blacklisting cfi and cfi-vcall work correctly
+// RUN: echo "[cfi-vcall]" > %t.vcall.txt
+// RUN: echo "type:std::*" >> %t.vcall.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.vcall.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+//
+// RUN: echo "[cfi]" > %t.cfi.txt
+// RUN: echo "type:std::*" >> %t.cfi.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.cfi.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+
+// Check that blacklisting non-vcall modes does not affect vcalls
+// RUN: echo "[cfi-icall|cfi-nvcall|cfi-cast-strict|cfi-derived-cast|cfi-unrelated-cast]" > %t.other.txt
+// RUN: echo "type:std::*" >> %t.other.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.other.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOBL %s
 
 struct S1 {
   virtual void f();
Index: test/CodeGen/sanitizer-special-case-list.c
===================================================================
--- /dev/null
+++ test/CodeGen/sanitizer-special-case-list.c
@@ -0,0 +1,47 @@
+// Verify that blacklist sections correctly select sanitizers to apply blacklist entries to.
+//
+// RUN: echo "fun:*cfi*" > %t.unsanitized1
+// RUN: echo "fun:*overflow*" >> %t.unsanitized1
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%t.unsanitized1 -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+//
+// RUN: echo "[cfi]" > %t.unsanitized2
+// RUN: echo "fun:*cfi*" >> %t.unsanitized2
+// RUN: echo "[unsigned-integer-overflow]" >> %t.unsanitized2
+// RUN: echo "fun:*overflow*" >> %t.unsanitized2
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%t.unsanitized2 -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+//
+// RUN: echo "[cfi-icall]" > %t.unsanitized3
+// RUN: echo "fun:*cfi*" >> %t.unsanitized3
+// RUN: echo "[unsigned-integer-overflow]" >> %t.unsanitized3
+// RUN: echo "fun:*overflow*" >> %t.unsanitized3
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%t.unsanitized3 -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+//
+// RUN: echo "[c*]" > %t.unsanitized4
+// RUN: echo "fun:*cfi*" >> %t.unsanitized4
+// RUN: echo "[u*]" >> %t.unsanitized4
+// RUN: echo "fun:*overflow*" >> %t.unsanitized4
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%t.unsanitized4 -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+//
+// RUN: echo "[unsigned-integer-overflow]" > %t.sanitized
+// RUN: echo "fun:*cfi*" >> %t.sanitized
+// RUN: echo "[cfi]" >> %t.sanitized
+// RUN: echo "fun:*overflow*" >> %t.sanitized
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%t.sanitized -emit-llvm %s -o - | FileCheck %s --check-prefix=SANITIZED
+
+unsigned i;
+
+// SANITIZED: @overflow
+// UNSANITIZED: @overflow
+unsigned overflow() {
+// SANITIZED: call {{.*}}void @__ubsan
+// UNSANITIZED-NOT: call {{.*}}void @__ubsan
+  return i * 37;
+}
+
+// SANITIZED: @cfi
+// UNSANITIZED: @cfi
+void cfi(void (*fp)()) {
+// SANITIZED: llvm.type.test
+// UNSANITIZED-NOT: llvm.type.test
+  fp();
+}
Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1106,7 +1106,7 @@
   /// annotations are emitted during finalization of the LLVM code.
   void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV);
 
-  bool isInSanitizerBlacklist(llvm::Function *Fn, SourceLocation Loc) const;
+  bool isInSanitizerBlacklist(SanitizerMask Kind, llvm::Function *Fn, SourceLocation Loc) const;
 
   bool isInSanitizerBlacklist(llvm::GlobalVariable *GV, SourceLocation Loc,
                               QualType Ty,
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -1538,35 +1538,37 @@
     Annotations.push_back(EmitAnnotateAttr(GV, I, D->getLocation()));
 }
 
-bool CodeGenModule::isInSanitizerBlacklist(llvm::Function *Fn,
+bool CodeGenModule::isInSanitizerBlacklist(SanitizerMask Kind,
+                                           llvm::Function *Fn,
                                            SourceLocation Loc) const {
   const auto &SanitizerBL = getContext().getSanitizerBlacklist();
   // Blacklist by function name.
-  if (SanitizerBL.isBlacklistedFunction(Fn->getName()))
+  if (SanitizerBL.isBlacklistedFunction(Kind, Fn->getName()))
     return true;
   // Blacklist by location.
   if (Loc.isValid())
-    return SanitizerBL.isBlacklistedLocation(Loc);
+    return SanitizerBL.isBlacklistedLocation(Kind, Loc);
   // If location is unknown, this may be a compiler-generated function. Assume
   // it's located in the main file.
   auto &SM = Context.getSourceManager();
   if (const auto *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
-    return SanitizerBL.isBlacklistedFile(MainFile->getName());
+    return SanitizerBL.isBlacklistedFile(Kind, MainFile->getName());
   }
   return false;
 }
 
 bool CodeGenModule::isInSanitizerBlacklist(llvm::GlobalVariable *GV,
                                            SourceLocation Loc, QualType Ty,
                                            StringRef Category) const {
   // For now globals can be blacklisted only in ASan and KASan.
-  if (!LangOpts.Sanitize.hasOneOf(
-          SanitizerKind::Address | SanitizerKind::KernelAddress))
+  const SanitizerMask ASanMask =
+      SanitizerKind::Address | SanitizerKind::KernelAddress;
+  if (!LangOpts.Sanitize.hasOneOf(ASanMask))
     return false;
   const auto &SanitizerBL = getContext().getSanitizerBlacklist();
-  if (SanitizerBL.isBlacklistedGlobal(GV->getName(), Category))
+  if (SanitizerBL.isBlacklistedGlobal(ASanMask, GV->getName(), Category))
     return true;
-  if (SanitizerBL.isBlacklistedLocation(Loc, Category))
+  if (SanitizerBL.isBlacklistedLocation(ASanMask, Loc, Category))
     return true;
   // Check global type.
   if (!Ty.isNull()) {
@@ -1578,7 +1580,7 @@
     // We allow to blacklist only record types (classes, structs etc.)
     if (Ty->isRecordType()) {
       std::string TypeStr = Ty.getAsString(getContext().getPrintingPolicy());
-      if (SanitizerBL.isBlacklistedType(TypeStr, Category))
+      if (SanitizerBL.isBlacklistedType(ASanMask, TypeStr, Category))
         return true;
     }
   }
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -804,8 +804,19 @@
   CurFnInfo = &FnInfo;
   assert(CurFn->isDeclaration() && "Function already has body?");
 
-  if (CGM.isInSanitizerBlacklist(Fn, Loc))
-    SanOpts.clear();
+  // If this function has been blacklisted for any of the enabled sanitizers,
+  // disable the sanitizer for the function.
+  do {
+#define SANITIZER(NAME, ID)                                                    \
+  if (SanOpts.empty())                                                         \
+    break;                                                                     \
+  if (SanOpts.has(SanitizerKind::ID))                                          \
+    if (CGM.isInSanitizerBlacklist(SanitizerKind::ID, Fn, Loc))                \
+      SanOpts.set(SanitizerKind::ID, false);
+
+#include "clang/Basic/Sanitizers.def"
+#undef SANITIZER
+  } while (0);
 
   if (D) {
     // Apply the no_sanitize* attributes to SanOpts.
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -725,7 +725,7 @@
 
     // Blacklist based on the mangled type.
     if (!CGM.getContext().getSanitizerBlacklist().isBlacklistedType(
-            Out.str())) {
+            SanitizerKind::Vptr, Out.str())) {
       llvm::hash_code TypeHash = hash_value(Out.str());
 
       // Load the vptr, and compute hash_16_bytes(TypeHash, vptr).
Index: lib/CodeGen/CGDeclCXX.cpp
===================================================================
--- lib/CodeGen/CGDeclCXX.cpp
+++ lib/CodeGen/CGDeclCXX.cpp
@@ -316,17 +316,23 @@
   if (!getLangOpts().Exceptions)
     Fn->setDoesNotThrow();
 
-  if (!isInSanitizerBlacklist(Fn, Loc)) {
-    if (getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
-                                        SanitizerKind::KernelAddress))
+  SanitizerMask ASanMask =
+      SanitizerKind::Address | SanitizerKind::KernelAddress;
+  if (getLangOpts().Sanitize.hasOneOf(ASanMask))
+    if (!isInSanitizerBlacklist(ASanMask, Fn, Loc))
       Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
-    if (getLangOpts().Sanitize.has(SanitizerKind::Thread))
+
+  if (getLangOpts().Sanitize.has(SanitizerKind::Thread))
+    if (!isInSanitizerBlacklist(SanitizerKind::Thread, Fn, Loc))
       Fn->addFnAttr(llvm::Attribute::SanitizeThread);
-    if (getLangOpts().Sanitize.has(SanitizerKind::Memory))
+
+  if (getLangOpts().Sanitize.has(SanitizerKind::Memory))
+    if (!isInSanitizerBlacklist(SanitizerKind::Memory, Fn, Loc))
       Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
-    if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack))
+
+  if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack))
+    if (!isInSanitizerBlacklist(SanitizerKind::SafeStack, Fn, Loc))
       Fn->addFnAttr(llvm::Attribute::SafeStack);
-  }
 
   return Fn;
 }
Index: lib/CodeGen/CGClass.cpp
===================================================================
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -2603,28 +2603,34 @@
       !CGM.HasHiddenLTOVisibility(RD))
     return;
 
-  std::string TypeName = RD->getQualifiedNameAsString();
-  if (getContext().getSanitizerBlacklist().isBlacklistedType(TypeName))
-    return;
-
-  SanitizerScope SanScope(this);
+  SanitizerMask M;
   llvm::SanitizerStatKind SSK;
   switch (TCK) {
   case CFITCK_VCall:
+    M = SanitizerKind::CFIVCall;
     SSK = llvm::SanStat_CFI_VCall;
     break;
   case CFITCK_NVCall:
+    M = SanitizerKind::CFINVCall;
     SSK = llvm::SanStat_CFI_NVCall;
     break;
   case CFITCK_DerivedCast:
+    M = SanitizerKind::CFIDerivedCast;
     SSK = llvm::SanStat_CFI_DerivedCast;
     break;
   case CFITCK_UnrelatedCast:
+    M = SanitizerKind::CFIUnrelatedCast;
     SSK = llvm::SanStat_CFI_UnrelatedCast;
     break;
   case CFITCK_ICall:
     llvm_unreachable("not expecting CFITCK_ICall");
   }
+
+  std::string TypeName = RD->getQualifiedNameAsString();
+  if (getContext().getSanitizerBlacklist().isBlacklistedType(M, TypeName))
+    return;
+
+  SanitizerScope SanScope(this);
   EmitSanitizerStatReport(SSK);
 
   llvm::Metadata *MD =
@@ -2635,24 +2641,6 @@
   llvm::Value *TypeTest = Builder.CreateCall(
       CGM.getIntrinsic(llvm::Intrinsic::type_test), {CastedVTable, TypeId});
 
-  SanitizerMask M;
-  switch (TCK) {
-  case CFITCK_VCall:
-    M = SanitizerKind::CFIVCall;
-    break;
-  case CFITCK_NVCall:
-    M = SanitizerKind::CFINVCall;
-    break;
-  case CFITCK_DerivedCast:
-    M = SanitizerKind::CFIDerivedCast;
-    break;
-  case CFITCK_UnrelatedCast:
-    M = SanitizerKind::CFIUnrelatedCast;
-    break;
-  case CFITCK_ICall:
-    llvm_unreachable("not expecting CFITCK_ICall");
-  }
-
   llvm::Constant *StaticData[] = {
       llvm::ConstantInt::get(Int8Ty, TCK),
       EmitCheckSourceLocation(Loc),
@@ -2687,7 +2675,8 @@
     return false;
 
   std::string TypeName = RD->getQualifiedNameAsString();
-  return !getContext().getSanitizerBlacklist().isBlacklistedType(TypeName);
+  return !getContext().getSanitizerBlacklist().isBlacklistedType(
+      SanitizerKind::CFIVCall, TypeName);
 }
 
 llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
Index: lib/Basic/XRayLists.cpp
===================================================================
--- lib/Basic/XRayLists.cpp
+++ lib/Basic/XRayLists.cpp
@@ -26,21 +26,26 @@
 XRayFunctionFilter::shouldImbueFunction(StringRef FunctionName) const {
   // First apply the always instrument list, than if it isn't an "always" see
   // whether it's treated as a "never" instrument function.
-  if (AlwaysInstrument->inSection("fun", FunctionName, "arg1"))
+  if (AlwaysInstrument->inSection("xray_always_instrument", "fun",
+                                  FunctionName, "arg1"))
     return ImbueAttribute::ALWAYS_ARG1;
-  if (AlwaysInstrument->inSection("fun", FunctionName))
+  if (AlwaysInstrument->inSection("xray_always_instrument", "fun",
+                                  FunctionName))
     return ImbueAttribute::ALWAYS;
-  if (NeverInstrument->inSection("fun", FunctionName))
+  if (NeverInstrument->inSection("xray_never_instrument", "fun",
+                                 FunctionName))
     return ImbueAttribute::NEVER;
   return ImbueAttribute::NONE;
 }
 
 XRayFunctionFilter::ImbueAttribute
 XRayFunctionFilter::shouldImbueFunctionsInFile(StringRef Filename,
                                                StringRef Category) const {
-  if (AlwaysInstrument->inSection("src", Filename, Category))
+  if (AlwaysInstrument->inSection("xray_always_instrument", "src", Filename,
+                                  Category))
     return ImbueAttribute::ALWAYS;
-  if (NeverInstrument->inSection("src", Filename, Category))
+  if (NeverInstrument->inSection("xray_never_instrument", "src", Filename,
+                                 Category))
     return ImbueAttribute::NEVER;
   return ImbueAttribute::NONE;
 }
Index: lib/Basic/SanitizerSpecialCaseList.cpp
===================================================================
--- /dev/null
+++ lib/Basic/SanitizerSpecialCaseList.cpp
@@ -0,0 +1,68 @@
+//===--- SanitizerSpecialCaseList.cpp - SCL for sanitizers ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// An extension of SpecialCaseList to allowing querying sections by
+// SanitizerMask.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Basic/SanitizerSpecialCaseList.h"
+
+using namespace clang;
+
+std::unique_ptr<SanitizerSpecialCaseList>
+SanitizerSpecialCaseList::create(const std::vector<std::string> &Paths,
+                                 std::string &Error) {
+  std::unique_ptr<clang::SanitizerSpecialCaseList> SSCL(
+      new SanitizerSpecialCaseList());
+  if (SSCL->createInternal(Paths, Error))
+    return SSCL;
+  return nullptr;
+}
+
+std::unique_ptr<SanitizerSpecialCaseList>
+SanitizerSpecialCaseList::createOrDie(const std::vector<std::string> &Paths) {
+  std::string Error;
+  if (auto SSCL = create(Paths, Error))
+    return SSCL;
+  llvm::report_fatal_error(Error);
+}
+
+void SanitizerSpecialCaseList::compile(
+    llvm::StringMap<SectionEntries> &SectionsMap) {
+  SpecialCaseList::compile(SectionsMap);
+
+  for (auto &S : Sections) {
+    SanitizerMask Mask = 0;
+
+#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
+
+    SanitizerSection SS(Mask, S.Entries);
+    SanitizerSections.push_back(std::move(SS));
+  }
+}
+
+bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask,
+                                         StringRef Prefix,
+                                         StringRef Query,
+                                         StringRef Category) const {
+  for (auto &S : SanitizerSections)
+    if ((S.Mask & Mask) &&
+        SpecialCaseList::inSection(S.Entries, Prefix, Query, Category))
+      return true;
+
+  return false;
+}
+
Index: lib/Basic/SanitizerBlacklist.cpp
===================================================================
--- lib/Basic/SanitizerBlacklist.cpp
+++ lib/Basic/SanitizerBlacklist.cpp
@@ -17,30 +17,35 @@
 
 SanitizerBlacklist::SanitizerBlacklist(
     const std::vector<std::string> &BlacklistPaths, SourceManager &SM)
-    : SCL(llvm::SpecialCaseList::createOrDie(BlacklistPaths)), SM(SM) {}
+    : SSCL(SanitizerSpecialCaseList::createOrDie(BlacklistPaths)), SM(SM) {}
 
-bool SanitizerBlacklist::isBlacklistedGlobal(StringRef GlobalName,
+bool SanitizerBlacklist::isBlacklistedGlobal(SanitizerMask Mask,
+                                             StringRef GlobalName,
                                              StringRef Category) const {
-  return SCL->inSection("global", GlobalName, Category);
+  return SSCL->inSection(Mask, "global", GlobalName, Category);
 }
 
-bool SanitizerBlacklist::isBlacklistedType(StringRef MangledTypeName,
+bool SanitizerBlacklist::isBlacklistedType(SanitizerMask Mask,
+                                           StringRef MangledTypeName,
                                            StringRef Category) const {
-  return SCL->inSection("type", MangledTypeName, Category);
+  return SSCL->inSection(Mask, "type", MangledTypeName, Category);
 }
 
-bool SanitizerBlacklist::isBlacklistedFunction(StringRef FunctionName) const {
-  return SCL->inSection("fun", FunctionName);
+bool SanitizerBlacklist::isBlacklistedFunction(SanitizerMask Mask,
+                                               StringRef FunctionName) const {
+  return SSCL->inSection(Mask, "fun", FunctionName);
 }
 
-bool SanitizerBlacklist::isBlacklistedFile(StringRef FileName,
+bool SanitizerBlacklist::isBlacklistedFile(SanitizerMask Mask,
+                                           StringRef FileName,
                                            StringRef Category) const {
-  return SCL->inSection("src", FileName, Category);
+  return SSCL->inSection(Mask, "src", FileName, Category);
 }
 
-bool SanitizerBlacklist::isBlacklistedLocation(SourceLocation Loc,
+bool SanitizerBlacklist::isBlacklistedLocation(SanitizerMask Mask,
+                                               SourceLocation Loc,
                                                StringRef Category) const {
   return Loc.isValid() &&
-         isBlacklistedFile(SM.getFilename(SM.getFileLoc(Loc)), Category);
+         isBlacklistedFile(Mask, SM.getFilename(SM.getFileLoc(Loc)), Category);
 }
 
Index: lib/Basic/CMakeLists.txt
===================================================================
--- lib/Basic/CMakeLists.txt
+++ lib/Basic/CMakeLists.txt
@@ -62,6 +62,7 @@
   OpenMPKinds.cpp
   OperatorPrecedence.cpp
   SanitizerBlacklist.cpp
+  SanitizerSpecialCaseList.cpp
   Sanitizers.cpp
   SourceLocation.cpp
   SourceManager.cpp
Index: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -3929,8 +3929,9 @@
 
 bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const {
   ASTContext &Context = getASTContext();
-  if (!Context.getLangOpts().Sanitize.hasOneOf(
-          SanitizerKind::Address | SanitizerKind::KernelAddress) ||
+  const SanitizerMask ASanMask =
+      SanitizerKind::Address | SanitizerKind::KernelAddress;
+  if (!Context.getLangOpts().Sanitize.hasOneOf(ASanMask) ||
       !Context.getLangOpts().SanitizeAddressFieldPadding)
     return false;
   const auto &Blacklist = Context.getSanitizerBlacklist();
@@ -3949,9 +3950,10 @@
     ReasonToReject = 4;  // has trivial destructor.
   else if (CXXRD->isStandardLayout())
     ReasonToReject = 5;  // is standard layout.
-  else if (Blacklist.isBlacklistedLocation(getLocation(), "field-padding"))
+  else if (Blacklist.isBlacklistedLocation(ASanMask, getLocation(),
+                                           "field-padding"))
     ReasonToReject = 6;  // is in a blacklisted file.
-  else if (Blacklist.isBlacklistedType(getQualifiedNameAsString(),
+  else if (Blacklist.isBlacklistedType(ASanMask, getQualifiedNameAsString(),
                                        "field-padding"))
     ReasonToReject = 7;  // is blacklisted.
 
Index: include/clang/Basic/SanitizerSpecialCaseList.h
===================================================================
--- /dev/null
+++ include/clang/Basic/SanitizerSpecialCaseList.h
@@ -0,0 +1,53 @@
+//===--- SanitizerSpecialCaseList.h - SCL for sanitizers --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// An extension of SpecialCaseList to allowing querying sections by
+// SanitizerMask.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_SANITIZERSPECIALCASELIST_H
+#define LLVM_CLANG_BASIC_SANITIZERSPECIALCASELIST_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Sanitizers.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SpecialCaseList.h"
+#include <memory>
+
+namespace clang {
+
+class SanitizerSpecialCaseList : public llvm::SpecialCaseList {
+public:
+  static std::unique_ptr<SanitizerSpecialCaseList>
+  create(const std::vector<std::string> &Paths, std::string &Error);
+
+  static std::unique_ptr<SanitizerSpecialCaseList>
+  createOrDie(const std::vector<std::string> &Paths);
+
+  bool inSection(SanitizerMask Mask, StringRef Prefix, StringRef Query,
+                 StringRef Category = StringRef()) const;
+
+protected:
+  // Override compile to also initialize SanitizerSections.
+  virtual void compile(llvm::StringMap<SectionEntries> &SectionsMap);
+
+  struct SanitizerSection {
+    SanitizerSection(SanitizerMask SM, SectionEntries &E)
+        : Mask(SM),Entries(E) {};
+
+    SanitizerMask Mask;
+    SectionEntries &Entries;
+  };
+
+  std::vector<SanitizerSection> SanitizerSections;
+};
+
+}  // end namespace clang
+
+#endif
Index: include/clang/Basic/SanitizerBlacklist.h
===================================================================
--- include/clang/Basic/SanitizerBlacklist.h
+++ include/clang/Basic/SanitizerBlacklist.h
@@ -15,29 +15,30 @@
 #define LLVM_CLANG_BASIC_SANITIZERBLACKLIST_H
 
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/Sanitizers.h"
+#include "clang/Basic/SanitizerSpecialCaseList.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/Support/SpecialCaseList.h"
 #include <memory>
 
 namespace clang {
 
 class SanitizerBlacklist {
-  std::unique_ptr<llvm::SpecialCaseList> SCL;
+  std::unique_ptr<SanitizerSpecialCaseList> SSCL;
   SourceManager &SM;
 
 public:
   SanitizerBlacklist(const std::vector<std::string> &BlacklistPaths,
                      SourceManager &SM);
-  bool isBlacklistedGlobal(StringRef GlobalName,
+  bool isBlacklistedGlobal(SanitizerMask Mask, StringRef GlobalName,
                            StringRef Category = StringRef()) const;
-  bool isBlacklistedType(StringRef MangledTypeName,
+  bool isBlacklistedType(SanitizerMask Mask, StringRef MangledTypeName,
                          StringRef Category = StringRef()) const;
-  bool isBlacklistedFunction(StringRef FunctionName) const;
-  bool isBlacklistedFile(StringRef FileName,
+  bool isBlacklistedFunction(SanitizerMask Mask, StringRef FunctionName) const;
+  bool isBlacklistedFile(SanitizerMask Mask, StringRef FileName,
                          StringRef Category = StringRef()) const;
-  bool isBlacklistedLocation(SourceLocation Loc,
+  bool isBlacklistedLocation(SanitizerMask Mask, SourceLocation Loc,
                              StringRef Category = StringRef()) const;
 };
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to