diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index e3adaec2f3a8..9a77f9d00784 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/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(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan " + "field padding (0: none, 1:least " + "aggressive, 2: more aggressive)") + #undef LANGOPT #undef COMPATIBLE_LANGOPT #undef BENIGN_LANGOPT diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 50958777b3d9..5ac96c519855 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -24,29 +24,6 @@ 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 /// this large collection of bitfields is a trivial class type. class LangOptionsBase { @@ -56,7 +33,6 @@ public: #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) #include "clang/Basic/LangOptions.def" - SanitizerOptions Sanitize; protected: // Define language options of enumeration type. These are private, and will // have accessors (below). @@ -91,6 +67,13 @@ public: enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off }; 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; std::string ObjCConstantStringClass; diff --git a/clang/include/clang/Basic/Sanitizers.h b/clang/include/clang/Basic/Sanitizers.h index d3bea8b761b7..423eaf6246d3 100644 --- a/clang/include/clang/Basic/Sanitizers.h +++ b/clang/include/clang/Basic/Sanitizers.h @@ -23,6 +23,22 @@ enum class SanitizerKind { 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 #endif diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index ba581396d987..dd67c9f73d38 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -738,7 +738,7 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM, BlockDescriptorExtendedType(nullptr), cudaConfigureCallDecl(nullptr), NullTypeSourceInfo(QualType()), FirstLocalImport(), LastLocalImport(), SourceMgr(SM), LangOpts(LOpts), - SanitizerBL(new SanitizerBlacklist(LangOpts.Sanitize.BlacklistFile, SM)), + SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFile, SM)), AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts), Idents(idents), Selectors(sels), BuiltinInfo(builtins), DeclarationNames(*this), ExternalSource(nullptr), Listener(nullptr), diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 638ed8d9b086..a937fdf09209 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3628,7 +3628,7 @@ void RecordDecl::LoadFieldsFromExternalStorage() const { bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const { ASTContext &Context = getASTContext(); if (!Context.getLangOpts().Sanitize.has(SanitizerKind::Address) || - !Context.getLangOpts().Sanitize.SanitizeAddressFieldPadding) + !Context.getLangOpts().SanitizeAddressFieldPadding) return false; const auto &Blacklist = Context.getSanitizerBlacklist(); const CXXRecordDecl *CXXRD = dyn_cast(this); diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt index 2ecbf0aef670..3bcbc89f8ca4 100644 --- a/clang/lib/Basic/CMakeLists.txt +++ b/clang/lib/Basic/CMakeLists.txt @@ -19,6 +19,7 @@ add_clang_library(clangBasic OpenMPKinds.cpp OperatorPrecedence.cpp SanitizerBlacklist.cpp + Sanitizers.cpp SourceLocation.cpp SourceManager.cpp TargetInfo.cpp diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp index 8992bfaff2b4..dcbd22817111 100644 --- a/clang/lib/Basic/LangOptions.cpp +++ b/clang/lib/Basic/LangOptions.cpp @@ -14,24 +14,6 @@ using namespace clang; -SanitizerOptions::SanitizerOptions() - : Kind(0), SanitizeAddressFieldPadding(0) {} - -bool SanitizerOptions::has(SanitizerKind K) const { - unsigned Bit = static_cast(K); - return Kind & (1 << Bit); -} - -void SanitizerOptions::set(SanitizerKind K, bool Value) { - unsigned Bit = static_cast(K); - Kind = Value ? (Kind | (1 << Bit)) : (Kind & ~(1 << Bit)); -} - -void SanitizerOptions::clear() { - SanitizerOptions Default; - *this = std::move(Default); -} - LangOptions::LangOptions() { #define LANGOPT(Name, Bits, Default, Description) 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 // sanitizer options (this affects __has_feature(address_sanitizer) etc). Sanitize.clear(); + SanitizerBlacklistFile.clear(); CurrentModule.clear(); ImplementationOfModule.clear(); diff --git a/clang/lib/Basic/Sanitizers.cpp b/clang/lib/Basic/Sanitizers.cpp new file mode 100644 index 000000000000..7bc884dd0153 --- /dev/null +++ b/clang/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(K); + return Kinds & (1 << Bit); +} + +void SanitizerSet::set(SanitizerKind K, bool Value) { + unsigned Bit = static_cast(K); + Kinds = Value ? (Kinds | (1 << Bit)) : (Kinds & ~(1 << Bit)); +} + +void SanitizerSet::clear() { + Kinds = 0; +} diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 3d4e6bbe1d76..57675b1fe192 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -215,7 +215,7 @@ static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder, const PassManagerBuilderWrapper &BuilderWrapper = static_cast(Builder); const LangOptions &LangOpts = BuilderWrapper.getLangOpts(); - PM.add(createDataFlowSanitizerPass(LangOpts.Sanitize.BlacklistFile)); + PM.add(createDataFlowSanitizerPass(LangOpts.SanitizerBlacklistFile)); } static TargetLibraryInfo *createTLI(llvm::Triple &TargetTriple, diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 1a4c1564270f..f64b8fef3fae 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -842,7 +842,7 @@ namespace { } private: CodeGenFunction &CGF; - SanitizerOptions OldSanOpts; + SanitizerSet OldSanOpts; }; } @@ -858,7 +858,7 @@ namespace { bool isMemcpyableField(FieldDecl *F) const { // Never memcpy fields when we are adding poisoned paddings. - if (CGF.getContext().getLangOpts().Sanitize.SanitizeAddressFieldPadding) + if (CGF.getContext().getLangOpts().SanitizeAddressFieldPadding) return false; Qualifiers Qual = F->getType().getQualifiers(); if (Qual.hasVolatile() || Qual.hasObjCLifetime()) diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index de2f4daed9ba..013fdc0ed226 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -248,8 +248,8 @@ public: /// potentially higher performance penalties. 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. bool IsSanitizerScope; diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index f4665884cf5f..add0c9bdb231 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1622,9 +1622,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.Sanitize.set(K, true); } // -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); - Opts.Sanitize.BlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist); + Opts.SanitizerBlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist); } static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,