From: Alexey Samsonov Date: Fri, 9 Aug 2013 07:42:13 +0000 (+0000) Subject: Make SanitizerArgs parsing toolchain-independent X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8bdc92c01eeb345042b99650c6860b6aaa683ad8;p=clang Make SanitizerArgs parsing toolchain-independent git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188058 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp index 69221ab13a..8851316c83 100644 --- a/lib/Driver/SanitizerArgs.cpp +++ b/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(Value) #define SANITIZER(NAME, ID) .Case(NAME, ID) diff --git a/lib/Driver/SanitizerArgs.h b/lib/Driver/SanitizerArgs.h index 05886768cf..8776022edd 100644 --- a/lib/Driver/SanitizerArgs.h +++ b/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/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 5defac6eed..56f3e320fa 100644 --- a/lib/Driver/ToolChains.cpp +++ b/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/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 1d41b94b7f..69b6378b45 100644 --- a/lib/Driver/Tools.cpp +++ b/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;