From e21afe131a825f27d71230f4cca327945207a08c Mon Sep 17 00:00:00 2001
From: Alexey Samsonov <vonosmas@gmail.com>
Date: Wed, 9 Jul 2014 19:40:08 +0000
Subject: [PATCH] Decouple llvm::SpecialCaseList text representation and its
 LLVM IR semantics.

Turn llvm::SpecialCaseList into a simple class that parses text files in
a specified format and knows nothing about LLVM IR. Move this class into
LLVMSupport library. Implement two users of this class:
  * DFSanABIList in DFSan instrumentation pass.
  * SanitizerBlacklist in Clang CodeGen library.
The latter will be modified to use actual source-level information from frontend
(source file names) instead of unstable LLVM IR things (LLVM Module identifier).

Remove dependency edge from ClangCodeGen/ClangDriver to LLVMTransformUtils.

No functionality change.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@212643 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CMakeLists.txt         |  2 +-
 lib/CodeGen/CodeGenModule.cpp      | 11 ++++---
 lib/CodeGen/CodeGenModule.h        |  8 ++---
 lib/CodeGen/SanitizerBlacklist.cpp | 48 ++++++++++++++++++++++++++++++
 lib/CodeGen/SanitizerBlacklist.h   | 45 ++++++++++++++++++++++++++++
 lib/Driver/CMakeLists.txt          |  1 -
 lib/Driver/SanitizerArgs.cpp       |  2 +-
 7 files changed, 104 insertions(+), 13 deletions(-)
 create mode 100644 lib/CodeGen/SanitizerBlacklist.cpp
 create mode 100644 lib/CodeGen/SanitizerBlacklist.h

diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index bb655c263fc..2bf82e84735 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -13,7 +13,6 @@ set(LLVM_LINK_COMPONENTS
   ScalarOpts
   Support
   Target
-  TransformUtils
   )
 
 add_clang_library(clangCodeGen
@@ -60,6 +59,7 @@ add_clang_library(clangCodeGen
   ItaniumCXXABI.cpp
   MicrosoftCXXABI.cpp
   ModuleBuilder.cpp
+  SanitizerBlacklist.cpp
   TargetInfo.cpp
 
   DEPENDS
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index e5d72241262..d0563b25bdf 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -87,9 +87,8 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
       NSConcreteStackBlock(nullptr), BlockObjectAssign(nullptr),
       BlockObjectDispose(nullptr), BlockDescriptorType(nullptr),
       GenericBlockLiteralType(nullptr), LifetimeStartFn(nullptr),
-      LifetimeEndFn(nullptr),
-      SanitizerBlacklist(
-          llvm::SpecialCaseList::createOrDie(CGO.SanitizerBlacklistFile)) {
+      LifetimeEndFn(nullptr), SanitizerBL(llvm::SpecialCaseList::createOrDie(
+                                  CGO.SanitizerBlacklistFile)) {
 
   // Initialize the type cache.
   llvm::LLVMContext &LLVMContext = M.getContext();
@@ -730,7 +729,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
     B.addAttribute(llvm::Attribute::StackProtectReq);
 
   // Add sanitizer attributes if function is not blacklisted.
-  if (!SanitizerBlacklist->isIn(*F)) {
+  if (!SanitizerBL.isIn(*F)) {
     // When AddressSanitizer is enabled, set SanitizeAddress attribute
     // unless __attribute__((no_sanitize_address)) is used.
     if (LangOpts.Sanitize.Address && !D->hasAttr<NoSanitizeAddressAttr>())
@@ -1965,8 +1964,8 @@ void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV,
                                        SourceLocation Loc, bool IsDynInit) {
   if (!LangOpts.Sanitize.Address)
     return;
-  IsDynInit &= !SanitizerBlacklist->isIn(*GV, "init");
-  bool IsBlacklisted = SanitizerBlacklist->isIn(*GV);
+  IsDynInit &= !SanitizerBL.isIn(*GV, "init");
+  bool IsBlacklisted = SanitizerBL.isIn(*GV);
 
   llvm::LLVMContext &LLVMCtx = TheModule.getContext();
 
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index bb4c010cca4..649b0e54603 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -16,6 +16,7 @@
 
 #include "CGVTables.h"
 #include "CodeGenTypes.h"
+#include "SanitizerBlacklist.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
@@ -31,7 +32,6 @@
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/ValueHandle.h"
-#include "llvm/Transforms/Utils/SpecialCaseList.h"
 
 namespace llvm {
 class Module;
@@ -473,7 +473,7 @@ class CodeGenModule : public CodeGenTypeCache {
 
   GlobalDecl initializedGlobalDecl;
 
-  std::unique_ptr<llvm::SpecialCaseList> SanitizerBlacklist;
+  SanitizerBlacklist SanitizerBL;
 
   /// @}
 public:
@@ -1008,8 +1008,8 @@ public:
   /// annotations are emitted during finalization of the LLVM code.
   void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV);
 
-  const llvm::SpecialCaseList &getSanitizerBlacklist() const {
-    return *SanitizerBlacklist;
+  const SanitizerBlacklist &getSanitizerBlacklist() const {
+    return SanitizerBL;
   }
 
   void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc,
diff --git a/lib/CodeGen/SanitizerBlacklist.cpp b/lib/CodeGen/SanitizerBlacklist.cpp
new file mode 100644
index 00000000000..60bdbe1d92e
--- /dev/null
+++ b/lib/CodeGen/SanitizerBlacklist.cpp
@@ -0,0 +1,48 @@
+//===--- SanitizerBlacklist.cpp - Blacklist for sanitizers ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// User-provided blacklist used to disable/alter instrumentation done in
+// sanitizers.
+//
+//===----------------------------------------------------------------------===//
+#include "SanitizerBlacklist.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/Module.h"
+
+using namespace clang;
+using namespace CodeGen;
+
+static StringRef GetGlobalTypeString(const llvm::GlobalValue &G) {
+  // Types of GlobalVariables are always pointer types.
+  llvm::Type *GType = G.getType()->getElementType();
+  // For now we support blacklisting struct types only.
+  if (llvm::StructType *SGType = dyn_cast<llvm::StructType>(GType)) {
+    if (!SGType->isLiteral())
+      return SGType->getName();
+  }
+  return "<unknown type>";
+}
+
+bool SanitizerBlacklist::isIn(const llvm::Module &M,
+                              const StringRef Category) const {
+  return SCL->inSection("src", M.getModuleIdentifier(), Category);
+}
+
+bool SanitizerBlacklist::isIn(const llvm::Function &F) const {
+  return isIn(*F.getParent()) ||
+         SCL->inSection("fun", F.getName(), "");
+}
+
+bool SanitizerBlacklist::isIn(const llvm::GlobalVariable &G,
+                              const StringRef Category) const {
+  return isIn(*G.getParent(), Category) ||
+         SCL->inSection("global", G.getName(), Category) ||
+         SCL->inSection("type", GetGlobalTypeString(G), Category);
+}
diff --git a/lib/CodeGen/SanitizerBlacklist.h b/lib/CodeGen/SanitizerBlacklist.h
new file mode 100644
index 00000000000..b8c283ccf4f
--- /dev/null
+++ b/lib/CodeGen/SanitizerBlacklist.h
@@ -0,0 +1,45 @@
+//===--- SanitizerBlacklist.h - Blacklist for sanitizers --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// User-provided blacklist used to disable/alter instrumentation done in
+// sanitizers.
+//
+//===----------------------------------------------------------------------===//
+#ifndef CLANG_CODEGEN_SANITIZERBLACKLIST_H
+#define CLANG_CODEGEN_SANITIZERBLACKLIST_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SpecialCaseList.h"
+#include <memory>
+
+namespace llvm {
+class GlobalVariable;
+class Function;
+class Module;
+}
+
+namespace clang {
+namespace CodeGen {
+
+class SanitizerBlacklist {
+  std::unique_ptr<llvm::SpecialCaseList> SCL;
+
+public:
+  SanitizerBlacklist(llvm::SpecialCaseList *SCL) : SCL(SCL) {}
+  bool isIn(const llvm::Module &M,
+            const StringRef Category = StringRef()) const;
+  bool isIn(const llvm::Function &F) const;
+  bool isIn(const llvm::GlobalVariable &G,
+            const StringRef Category = StringRef()) const;
+};
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
index e9e9d913f1c..33db5e9a9e1 100644
--- a/lib/Driver/CMakeLists.txt
+++ b/lib/Driver/CMakeLists.txt
@@ -1,7 +1,6 @@
 set(LLVM_LINK_COMPONENTS
   Option
   Support
-  TransformUtils
   )
 
 add_clang_library(clangDriver
diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp
index 6a34e89cb97..b64f0275768 100644
--- a/lib/Driver/SanitizerArgs.cpp
+++ b/lib/Driver/SanitizerArgs.cpp
@@ -15,7 +15,7 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
-#include "llvm/Transforms/Utils/SpecialCaseList.h"
+#include "llvm/Support/SpecialCaseList.h"
 #include <memory>
 
 using namespace clang::driver;
-- 
GitLab