Pārlūkot izejas kodu

[Sanitizer] Refactor sanitizer options in LangOptions.

Get rid of ugly SanitizerOptions class thrust into LangOptions:
* Make SanitizeAddressFieldPadding a regular language option,
  and rely on default behavior to initialize/reset it.
* Make SanitizerBlacklistFile a regular member LangOptions.
* Introduce the helper class "SanitizerSet" to represent the
  set of enabled sanitizers and make it a member of LangOptions.
  It is exactly the entity we want to cache and modify in CodeGenFunction,
  for instance. We'd also be able to reuse SanitizerSet in
  CodeGenOptions for storing the set of recoverable sanitizers,
  and in the Driver to represent the set of sanitizers
  turned on/off by the commandline flags.

No functionality change.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@221653 91177308-0d34-0410-b5e6-96231b3b80d8
Alexey Samsonov 10 gadi atpakaļ
vecāks
revīzija
edab6ac0eb

+ 4 - 0
include/clang/Basic/LangOptions.def

@@ -216,6 +216,10 @@ LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")
 
 
 LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
 LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
 
 
+LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan "
+                                           "field padding (0: none, 1:least "
+                                           "aggressive, 2: more aggressive)")
+
 #undef LANGOPT
 #undef LANGOPT
 #undef COMPATIBLE_LANGOPT
 #undef COMPATIBLE_LANGOPT
 #undef BENIGN_LANGOPT
 #undef BENIGN_LANGOPT

+ 7 - 24
include/clang/Basic/LangOptions.h

@@ -24,29 +24,6 @@
 
 
 namespace clang {
 namespace clang {
 
 
-class SanitizerOptions {
-  /// \brief Bitmask of enabled sanitizers.
-  unsigned Kind;
-public:
-  SanitizerOptions();
-
-  /// \brief Check if a certain sanitizer is enabled.
-  bool has(SanitizerKind K) const;
-  /// \brief Enable or disable a certain sanitizer.
-  void set(SanitizerKind K, bool Value);
-
-  /// \brief Controls how agressive is asan field padding (0: none, 1: least
-  /// aggressive, 2: more aggressive).
-  unsigned SanitizeAddressFieldPadding : 2;
-
-  /// \brief Path to blacklist file specifying which objects
-  /// (files, functions, variables) should not be instrumented.
-  std::string BlacklistFile;
-
-  /// \brief Disable all sanitizers.
-  void clear();
-};
-
 /// Bitfields of LangOptions, split out from LangOptions in order to ensure that
 /// Bitfields of LangOptions, split out from LangOptions in order to ensure that
 /// this large collection of bitfields is a trivial class type.
 /// this large collection of bitfields is a trivial class type.
 class LangOptionsBase {
 class LangOptionsBase {
@@ -56,7 +33,6 @@ public:
 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
 #include "clang/Basic/LangOptions.def"
 #include "clang/Basic/LangOptions.def"
 
 
-  SanitizerOptions Sanitize;
 protected:
 protected:
   // Define language options of enumeration type. These are private, and will
   // Define language options of enumeration type. These are private, and will
   // have accessors (below).
   // have accessors (below).
@@ -91,6 +67,13 @@ public:
   enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
   enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
 
 
 public:
 public:
+  /// \brief Set of enabled sanitizers.
+  SanitizerSet Sanitize;
+
+  /// \brief Path to blacklist file specifying which objects
+  /// (files, functions, variables) should not be instrumented.
+  std::string SanitizerBlacklistFile;
+
   clang::ObjCRuntime ObjCRuntime;
   clang::ObjCRuntime ObjCRuntime;
 
 
   std::string ObjCConstantStringClass;
   std::string ObjCConstantStringClass;

+ 16 - 0
include/clang/Basic/Sanitizers.h

@@ -23,6 +23,22 @@ enum class SanitizerKind {
   Unknown
   Unknown
 };
 };
 
 
+class SanitizerSet {
+  /// \brief Bitmask of enabled sanitizers.
+  unsigned Kinds;
+public:
+  SanitizerSet();
+
+  /// \brief Check if a certain sanitizer is enabled.
+  bool has(SanitizerKind K) const;
+
+  /// \brief Enable or disable a certain sanitizer.
+  void set(SanitizerKind K, bool Value);
+
+  /// \brief Disable all sanitizers.
+  void clear();
+};
+
 }  // end namespace clang
 }  // end namespace clang
 
 
 #endif
 #endif

+ 1 - 1
lib/AST/ASTContext.cpp

@@ -738,7 +738,7 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
       BlockDescriptorExtendedType(nullptr), cudaConfigureCallDecl(nullptr),
       BlockDescriptorExtendedType(nullptr), cudaConfigureCallDecl(nullptr),
       NullTypeSourceInfo(QualType()), FirstLocalImport(), LastLocalImport(),
       NullTypeSourceInfo(QualType()), FirstLocalImport(), LastLocalImport(),
       SourceMgr(SM), LangOpts(LOpts),
       SourceMgr(SM), LangOpts(LOpts),
-      SanitizerBL(new SanitizerBlacklist(LangOpts.Sanitize.BlacklistFile, SM)),
+      SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFile, SM)),
       AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts),
       AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts),
       Idents(idents), Selectors(sels), BuiltinInfo(builtins),
       Idents(idents), Selectors(sels), BuiltinInfo(builtins),
       DeclarationNames(*this), ExternalSource(nullptr), Listener(nullptr),
       DeclarationNames(*this), ExternalSource(nullptr), Listener(nullptr),

+ 1 - 1
lib/AST/Decl.cpp

@@ -3628,7 +3628,7 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
 bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const {
 bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const {
   ASTContext &Context = getASTContext();
   ASTContext &Context = getASTContext();
   if (!Context.getLangOpts().Sanitize.has(SanitizerKind::Address) ||
   if (!Context.getLangOpts().Sanitize.has(SanitizerKind::Address) ||
-      !Context.getLangOpts().Sanitize.SanitizeAddressFieldPadding)
+      !Context.getLangOpts().SanitizeAddressFieldPadding)
     return false;
     return false;
   const auto &Blacklist = Context.getSanitizerBlacklist();
   const auto &Blacklist = Context.getSanitizerBlacklist();
   const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(this);
   const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(this);

+ 1 - 0
lib/Basic/CMakeLists.txt

@@ -19,6 +19,7 @@ add_clang_library(clangBasic
   OpenMPKinds.cpp
   OpenMPKinds.cpp
   OperatorPrecedence.cpp
   OperatorPrecedence.cpp
   SanitizerBlacklist.cpp
   SanitizerBlacklist.cpp
+  Sanitizers.cpp
   SourceLocation.cpp
   SourceLocation.cpp
   SourceManager.cpp
   SourceManager.cpp
   TargetInfo.cpp
   TargetInfo.cpp

+ 1 - 18
lib/Basic/LangOptions.cpp

@@ -14,24 +14,6 @@
 
 
 using namespace clang;
 using namespace clang;
 
 
-SanitizerOptions::SanitizerOptions()
-    : Kind(0), SanitizeAddressFieldPadding(0) {}
-
-bool SanitizerOptions::has(SanitizerKind K) const {
-  unsigned Bit = static_cast<unsigned>(K);
-  return Kind & (1 << Bit);
-}
-
-void SanitizerOptions::set(SanitizerKind K, bool Value) {
-  unsigned Bit = static_cast<unsigned>(K);
-  Kind = Value ? (Kind | (1 << Bit)) : (Kind & ~(1 << Bit));
-}
-
-void SanitizerOptions::clear() {
-  SanitizerOptions Default;
-  *this = std::move(Default);
-}
-
 LangOptions::LangOptions() {
 LangOptions::LangOptions() {
 #define LANGOPT(Name, Bits, Default, Description) Name = Default;
 #define LANGOPT(Name, Bits, Default, Description) Name = Default;
 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) set##Name(Default);
 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) set##Name(Default);
@@ -48,6 +30,7 @@ void LangOptions::resetNonModularOptions() {
   // FIXME: This should not be reset; modules can be different with different
   // FIXME: This should not be reset; modules can be different with different
   // sanitizer options (this affects __has_feature(address_sanitizer) etc).
   // sanitizer options (this affects __has_feature(address_sanitizer) etc).
   Sanitize.clear();
   Sanitize.clear();
+  SanitizerBlacklistFile.clear();
 
 
   CurrentModule.clear();
   CurrentModule.clear();
   ImplementationOfModule.clear();
   ImplementationOfModule.clear();

+ 31 - 0
lib/Basic/Sanitizers.cpp

@@ -0,0 +1,31 @@
+//===--- Sanitizers.cpp - C Language Family Language Options ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the classes from Sanitizers.h
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Basic/Sanitizers.h"
+
+using namespace clang;
+
+SanitizerSet::SanitizerSet() : Kinds(0) {}
+
+bool SanitizerSet::has(SanitizerKind K) const {
+  unsigned Bit = static_cast<unsigned>(K);
+  return Kinds & (1 << Bit);
+}
+
+void SanitizerSet::set(SanitizerKind K, bool Value) {
+  unsigned Bit = static_cast<unsigned>(K);
+  Kinds = Value ? (Kinds | (1 << Bit)) : (Kinds & ~(1 << Bit));
+}
+
+void SanitizerSet::clear() {
+  Kinds = 0;
+}

+ 1 - 1
lib/CodeGen/BackendUtil.cpp

@@ -215,7 +215,7 @@ static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,
   const PassManagerBuilderWrapper &BuilderWrapper =
   const PassManagerBuilderWrapper &BuilderWrapper =
       static_cast<const PassManagerBuilderWrapper&>(Builder);
       static_cast<const PassManagerBuilderWrapper&>(Builder);
   const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
   const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
-  PM.add(createDataFlowSanitizerPass(LangOpts.Sanitize.BlacklistFile));
+  PM.add(createDataFlowSanitizerPass(LangOpts.SanitizerBlacklistFile));
 }
 }
 
 
 static TargetLibraryInfo *createTLI(llvm::Triple &TargetTriple,
 static TargetLibraryInfo *createTLI(llvm::Triple &TargetTriple,

+ 2 - 2
lib/CodeGen/CGClass.cpp

@@ -842,7 +842,7 @@ namespace {
     }
     }
   private:
   private:
     CodeGenFunction &CGF;
     CodeGenFunction &CGF;
-    SanitizerOptions OldSanOpts;
+    SanitizerSet OldSanOpts;
   };
   };
 }
 }
 
 
@@ -858,7 +858,7 @@ namespace {
 
 
     bool isMemcpyableField(FieldDecl *F) const {
     bool isMemcpyableField(FieldDecl *F) const {
       // Never memcpy fields when we are adding poisoned paddings.
       // Never memcpy fields when we are adding poisoned paddings.
-      if (CGF.getContext().getLangOpts().Sanitize.SanitizeAddressFieldPadding)
+      if (CGF.getContext().getLangOpts().SanitizeAddressFieldPadding)
         return false;
         return false;
       Qualifiers Qual = F->getType().getQualifiers();
       Qualifiers Qual = F->getType().getQualifiers();
       if (Qual.hasVolatile() || Qual.hasObjCLifetime())
       if (Qual.hasVolatile() || Qual.hasObjCLifetime())

+ 2 - 2
lib/CodeGen/CodeGenFunction.h

@@ -248,8 +248,8 @@ public:
   /// potentially higher performance penalties.
   /// potentially higher performance penalties.
   unsigned char BoundsChecking;
   unsigned char BoundsChecking;
 
 
-  /// \brief Sanitizer options to use for this function.
-  SanitizerOptions SanOpts;
+  /// \brief Sanitizers enabled for this function.
+  SanitizerSet SanOpts;
 
 
   /// \brief True if CodeGen currently emits code implementing sanitizer checks.
   /// \brief True if CodeGen currently emits code implementing sanitizer checks.
   bool IsSanitizerScope;
   bool IsSanitizerScope;

+ 2 - 2
lib/Frontend/CompilerInvocation.cpp

@@ -1622,9 +1622,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
       Opts.Sanitize.set(K, true);
       Opts.Sanitize.set(K, true);
   }
   }
   // -fsanitize-address-field-padding=N has to be a LangOpt, parse it here.
   // -fsanitize-address-field-padding=N has to be a LangOpt, parse it here.
-  Opts.Sanitize.SanitizeAddressFieldPadding =
+  Opts.SanitizeAddressFieldPadding =
       getLastArgIntValue(Args, OPT_fsanitize_address_field_padding, 0, Diags);
       getLastArgIntValue(Args, OPT_fsanitize_address_field_padding, 0, Diags);
-  Opts.Sanitize.BlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist);
+  Opts.SanitizerBlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist);
 }
 }
 
 
 static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
 static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,