diff options
author | Alexey Samsonov <samsonov@google.com> | 2013-08-09 07:42:13 +0000 |
---|---|---|
committer | Alexey Samsonov <samsonov@google.com> | 2013-08-09 07:42:13 +0000 |
commit | e620366aa3394e6d0e1103f1cb4f2dfd2a412380 (patch) | |
tree | aa4a96b3d9c8f96ad1bdf10a72037d798a5dbe8b | |
parent | e7c765fe52528180141dba13fd79520b2c3e28dc (diff) | |
download | bcm5719-llvm-e620366aa3394e6d0e1103f1cb4f2dfd2a412380.tar.gz bcm5719-llvm-e620366aa3394e6d0e1103f1cb4f2dfd2a412380.zip |
Make SanitizerArgs parsing toolchain-independent
llvm-svn: 188058
-rw-r--r-- | clang/lib/Driver/SanitizerArgs.cpp | 52 | ||||
-rw-r--r-- | clang/lib/Driver/SanitizerArgs.h | 20 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 10 |
4 files changed, 51 insertions, 35 deletions
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 69221ab13ae..8851316c83c 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -23,7 +23,7 @@ void SanitizerArgs::clear() { Kind = 0; BlacklistFile = ""; MsanTrackOrigins = false; - AsanZeroBaseShadow = false; + AsanZeroBaseShadow = AZBSK_Default; UbsanTrapOnError = false; } @@ -31,17 +31,16 @@ SanitizerArgs::SanitizerArgs() { clear(); } -SanitizerArgs::SanitizerArgs(const ToolChain &TC, +SanitizerArgs::SanitizerArgs(const Driver &D, const llvm::opt::ArgList &Args) { clear(); - parse(TC, Args); + parse(D, Args); } -void SanitizerArgs::parse(const ToolChain &TC, +void SanitizerArgs::parse(const Driver &D, const llvm::opt::ArgList &Args) { unsigned AllKinds = 0; // All kinds of sanitizers that were turned on // at least once (possibly, disabled further). - const Driver &D = TC.getDriver(); for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) { unsigned Add, Remove; if (!parse(D, Args, *I, Add, Remove, true)) @@ -145,25 +144,21 @@ void SanitizerArgs::parse(const ToolChain &TC, // Parse -f(no-)sanitize-address-zero-base-shadow options. if (NeedsAsan) { - bool IsAndroid = (TC.getTriple().getEnvironment() == llvm::Triple::Android); - bool ZeroBaseShadowDefault = IsAndroid; - AsanZeroBaseShadow = - Args.hasFlag(options::OPT_fsanitize_address_zero_base_shadow, - options::OPT_fno_sanitize_address_zero_base_shadow, - ZeroBaseShadowDefault); - // Zero-base shadow is a requirement on Android. - if (IsAndroid && !AsanZeroBaseShadow) { - D.Diag(diag::err_drv_argument_not_allowed_with) - << "-fno-sanitize-address-zero-base-shadow" - << lastArgumentForKind(D, Args, Address); - } + if (Arg *A = Args.getLastArg( + options::OPT_fsanitize_address_zero_base_shadow, + options::OPT_fno_sanitize_address_zero_base_shadow)) + AsanZeroBaseShadow = A->getOption().matches( + options::OPT_fsanitize_address_zero_base_shadow) + ? AZBSK_On + : AZBSK_Off; } } -void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args, +void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const { if (!Kind) return; + const Driver &D = TC.getDriver(); SmallString<256> SanitizeOpt("-fsanitize="); #define SANITIZER(NAME, ID) \ if (Kind & ID) \ @@ -180,15 +175,30 @@ void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args, if (MsanTrackOrigins) CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins")); - if (AsanZeroBaseShadow) - CmdArgs.push_back( - Args.MakeArgString("-fsanitize-address-zero-base-shadow")); + if (needsAsanRt()) { + if (hasAsanZeroBaseShadow(TC)) { + CmdArgs.push_back( + Args.MakeArgString("-fsanitize-address-zero-base-shadow")); + } else if (TC.getTriple().getEnvironment() == llvm::Triple::Android) { + // Zero-base shadow is a requirement on Android. + D.Diag(diag::err_drv_argument_not_allowed_with) + << "-fno-sanitize-address-zero-base-shadow" + << lastArgumentForKind(D, Args, Address); + } + } // Workaround for PR16386. if (needsMsanRt()) CmdArgs.push_back(Args.MakeArgString("-fno-assume-sane-operator-new")); } +bool SanitizerArgs::hasAsanZeroBaseShadow(const ToolChain &TC) const { + if (AsanZeroBaseShadow != AZBSK_Default) + return AsanZeroBaseShadow == AZBSK_On; + // Zero-base shadow is used by default only on Android. + return TC.getTriple().getEnvironment() == llvm::Triple::Android; +} + unsigned SanitizerArgs::parse(const char *Value) { unsigned ParsedKind = llvm::StringSwitch<SanitizeKind>(Value) #define SANITIZER(NAME, ID) .Case(NAME, ID) diff --git a/clang/lib/Driver/SanitizerArgs.h b/clang/lib/Driver/SanitizerArgs.h index 05886768cf5..8776022eddb 100644 --- a/clang/lib/Driver/SanitizerArgs.h +++ b/clang/lib/Driver/SanitizerArgs.h @@ -44,17 +44,22 @@ class SanitizerArgs { HasZeroBaseShadow = Thread | Memory | DataFlow }; unsigned Kind; + std::string BlacklistFile; bool MsanTrackOrigins; - bool AsanZeroBaseShadow; + enum AsanZeroBaseShadowKind { + AZBSK_Default, // Default value is toolchain-specific. + AZBSK_On, + AZBSK_Off + } AsanZeroBaseShadow; bool UbsanTrapOnError; public: SanitizerArgs(); /// Parses the sanitizer arguments from an argument list. - SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args); + SanitizerArgs(const Driver &D, const llvm::opt::ArgList &Args); - void parse(const ToolChain &TC, const llvm::opt::ArgList &Args); + void parse(const Driver &D, const llvm::opt::ArgList &Args); bool needsAsanRt() const { return Kind & NeedsAsanRt; } bool needsTsanRt() const { return Kind & NeedsTsanRt; } @@ -70,16 +75,17 @@ class SanitizerArgs { bool sanitizesVptr() const { return Kind & Vptr; } bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; } - bool hasZeroBaseShadow() const { - return (Kind & HasZeroBaseShadow) || AsanZeroBaseShadow; + bool hasZeroBaseShadow(const ToolChain &TC) const { + return (Kind & HasZeroBaseShadow) || hasAsanZeroBaseShadow(TC); } - - void addArgs(const llvm::opt::ArgList &Args, + void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; private: void clear(); + bool hasAsanZeroBaseShadow(const ToolChain &TC) const; + /// Parse a single value from a -fsanitize= or -fno-sanitize= value list. /// Returns OR of members of the \c SanitizeKind enumeration, or \c 0 /// if \p Value is not known. diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index 5defac6eedb..56f3e320faf 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -290,7 +290,7 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, } } - SanitizerArgs Sanitize(*this, Args); + SanitizerArgs Sanitize(getDriver(), Args); // Add Ubsan runtime library, if required. if (Sanitize.needsUbsanRt()) { @@ -2354,7 +2354,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) addPathIfExists(SysRoot + "/lib", Paths); addPathIfExists(SysRoot + "/usr/lib", Paths); - IsPIEDefault = SanitizerArgs(*this, Args).hasZeroBaseShadow(); + IsPIEDefault = SanitizerArgs(getDriver(), Args).hasZeroBaseShadow(*this); } bool Linux::HasNativeLLVMSupport() const { diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 1d41b94b7f1..69b6378b45e 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -2792,8 +2792,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree); Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type); - SanitizerArgs Sanitize(getToolChain(), Args); - Sanitize.addArgs(Args, CmdArgs); + SanitizerArgs Sanitize(D, Args); + Sanitize.addArgs(getToolChain(), Args, CmdArgs); if (!Args.hasFlag(options::OPT_fsanitize_recover, options::OPT_fno_sanitize_recover, @@ -4765,7 +4765,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_L); - SanitizerArgs Sanitize(getToolChain(), Args); + SanitizerArgs Sanitize(getToolChain().getDriver(), Args); // If we're building a dynamic lib with -fsanitize=address, // unresolved symbols may appear. Mark all // of them as dynamic_lookup. Linking executables is handled in @@ -6029,10 +6029,10 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, const Driver &D = ToolChain.getDriver(); const bool isAndroid = ToolChain.getTriple().getEnvironment() == llvm::Triple::Android; - SanitizerArgs Sanitize(getToolChain(), Args); + SanitizerArgs Sanitize(D, Args); const bool IsPIE = !Args.hasArg(options::OPT_shared) && - (Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow()); + (Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow(ToolChain)); ArgStringList CmdArgs; |