vlad.tsyrklevich updated this revision to Diff 115528.
vlad.tsyrklevich added a comment.

Address @eugenis' comments


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/Inputs/sanitizer-special-case-list.sanitized.txt
  test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized1.txt
  test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized2.txt
  test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized3.txt
  test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized4.txt
  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,26 @@
+// Verify that blacklist sections correctly select sanitizers to apply blacklist entries to.
+//
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.unsanitized1.txt -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.unsanitized2.txt -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.unsanitized3.txt -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.unsanitized4.txt -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+//
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.sanitized.txt -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: test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized4.txt
===================================================================
--- /dev/null
+++ test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized4.txt
@@ -0,0 +1,4 @@
+[c*]
+fun:*cfi*
+[u*]
+fun:*overflow*
Index: test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized3.txt
===================================================================
--- /dev/null
+++ test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized3.txt
@@ -0,0 +1,4 @@
+[cfi-icall]
+fun:*cfi*
+[unsigned-integer-overflow]
+fun:*overflow*
Index: test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized2.txt
===================================================================
--- /dev/null
+++ test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized2.txt
@@ -0,0 +1,4 @@
+[cfi]
+fun:*cfi*
+[unsigned-integer-overflow]
+fun:*overflow*
Index: test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized1.txt
===================================================================
--- /dev/null
+++ test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized1.txt
@@ -0,0 +1,2 @@
+fun:*cfi*
+fun:*overflow*
Index: test/CodeGen/Inputs/sanitizer-special-case-list.sanitized.txt
===================================================================
--- /dev/null
+++ test/CodeGen/Inputs/sanitizer-special-case-list.sanitized.txt
@@ -0,0 +1,4 @@
+[unsigned-integer-overflow]
+fun:*cfi*
+[cfi]
+fun:*overflow*
Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h
+++ lib/CodeGen/CodeGenModule.h
@@ -1106,7 +1106,8 @@
   /// 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,39 @@
     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;
+  // Only select blacklisted entries from the enabled sanitizer.
+  const SanitizerMask BLMask = ASanMask & LangOpts.Sanitize.Mask;
   const auto &SanitizerBL = getContext().getSanitizerBlacklist();
-  if (SanitizerBL.isBlacklistedGlobal(GV->getName(), Category))
+  if (SanitizerBL.isBlacklistedGlobal(BLMask, GV->getName(), Category))
     return true;
-  if (SanitizerBL.isBlacklistedLocation(Loc, Category))
+  if (SanitizerBL.isBlacklistedLocation(BLMask, Loc, Category))
     return true;
   // Check global type.
   if (!Ty.isNull()) {
@@ -1578,7 +1582,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(BLMask, 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))
-      Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
-    if (getLangOpts().Sanitize.has(SanitizerKind::Thread))
-      Fn->addFnAttr(llvm::Attribute::SanitizeThread);
-    if (getLangOpts().Sanitize.has(SanitizerKind::Memory))
-      Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
-    if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack))
-      Fn->addFnAttr(llvm::Attribute::SafeStack);
-  }
+  const SanitizerMask ASanMask =
+      SanitizerKind::Address | SanitizerKind::KernelAddress;
+  if (getLangOpts().Sanitize.hasOneOf(ASanMask) &&
+      !isInSanitizerBlacklist(ASanMask & getLangOpts().Sanitize.Mask, Fn, Loc))
+    Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
+
+  if (getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
+      !isInSanitizerBlacklist(SanitizerKind::Thread, Fn, Loc))
+    Fn->addFnAttr(llvm::Attribute::SanitizeThread);
+
+  if (getLangOpts().Sanitize.has(SanitizerKind::Memory) &&
+      !isInSanitizerBlacklist(SanitizerKind::Memory, Fn, Loc))
+    Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
+
+  if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack) &&
+      !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,25 @@
 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,66 @@
+//===--- 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,54 @@
+//===--- 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);
+
+  // Query blacklisted entries if any bit in Mask matches the entry's section.
+  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/SanitizerSpecialCaseList.h"
+#include "clang/Basic/Sanitizers.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