From: Alexey Samsonov Date: Mon, 19 Aug 2013 09:14:21 +0000 (+0000) Subject: Move SanitizerArgs to the clang Driver X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1b8f12d46c10169bb949372ec5fc4c58afc2ced1;p=clang Move SanitizerArgs to the clang Driver Summary: This change turns SanitizerArgs into high-level options stored in the Driver, which are parsed lazily. This fixes an issue of multiple copies of the same diagnostic message produced by sanitizer arguments parser. Reviewers: rsmith Reviewed By: rsmith CC: chandlerc, eugenis, cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1341 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188660 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index 5dc9437366..5edf26b639 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -15,6 +15,7 @@ #include "clang/Driver/Phases.h" #include "clang/Driver/Types.h" #include "clang/Driver/Util.h" +#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" @@ -42,6 +43,7 @@ namespace driver { class Compilation; class InputInfo; class JobAction; + class SanitizerArgs; class ToolChain; /// Driver - Encapsulate logic for constructing compilation processes @@ -177,6 +179,9 @@ private: /// stored in it, and will clean them up when torn down. mutable llvm::StringMap ToolChains; + /// Parsed arguments passed to sanitizer tools. + mutable llvm::OwningPtr SanitizerArguments; + private: /// TranslateInputArgs - Create a new derived argument list from the input /// arguments, after applying the standard argument translations. @@ -404,6 +409,10 @@ private: std::pair getIncludeExcludeOptionFlagMasks() const; public: + /// \brief Returns parsed arguments to sanitizer tools. + const SanitizerArgs & + getOrParseSanitizerArgs(const llvm::opt::ArgList &Args) const; + /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and /// return the grouped values as integers. Numbers which are not /// provided are set to 0. diff --git a/lib/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h similarity index 98% rename from lib/Driver/SanitizerArgs.h rename to include/clang/Driver/SanitizerArgs.h index 8776022edd..051e06bac9 100644 --- a/lib/Driver/SanitizerArgs.h +++ b/include/clang/Driver/SanitizerArgs.h @@ -59,8 +59,6 @@ class SanitizerArgs { /// Parses the sanitizer arguments from an argument list. SanitizerArgs(const Driver &D, 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; } bool needsMsanRt() const { return Kind & NeedsMsanRt; } diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index 1ba5cdeb99..ba7aa64e60 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -34,6 +34,7 @@ namespace driver { class Compilation; class Driver; class JobAction; + class SanitizerArgs; class Tool; /// ToolChain - Access to tools for a single platform. @@ -124,6 +125,8 @@ public: path_list &getProgramPaths() { return ProgramPaths; } const path_list &getProgramPaths() const { return ProgramPaths; } + const SanitizerArgs& getSanitizerArgs() const; + // Tool access. /// TranslateArgs - Create a new derived argument list for any argument diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 32a7d1aafd..f3b8beb94b 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -16,6 +16,7 @@ #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Job.h" #include "clang/Driver/Options.h" +#include "clang/Driver/SanitizerArgs.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" #include "llvm/ADT/ArrayRef.h" @@ -2051,3 +2052,10 @@ std::pair Driver::getIncludeExcludeOptionFlagMasks() const { return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask); } + +const SanitizerArgs & +Driver::getOrParseSanitizerArgs(const ArgList &Args) const { + if (!SanitizerArguments.get()) + SanitizerArguments.reset(new SanitizerArgs(*this, Args)); + return *SanitizerArguments.get(); +} diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp index fdabf7b2da..e0a66c3de7 100644 --- a/lib/Driver/SanitizerArgs.cpp +++ b/lib/Driver/SanitizerArgs.cpp @@ -6,7 +6,7 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#include "SanitizerArgs.h" +#include "clang/Driver/SanitizerArgs.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" @@ -31,14 +31,8 @@ SanitizerArgs::SanitizerArgs() { clear(); } -SanitizerArgs::SanitizerArgs(const Driver &D, - const llvm::opt::ArgList &Args) { +SanitizerArgs::SanitizerArgs(const Driver &D, const llvm::opt::ArgList &Args) { clear(); - parse(D, Args); -} - -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). for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) { diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index 4fe3560976..ca74395955 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -42,6 +42,10 @@ bool ToolChain::useIntegratedAs() const { IsIntegratedAssemblerDefault()); } +const SanitizerArgs& ToolChain::getSanitizerArgs() const { + return D.getOrParseSanitizerArgs(Args); +} + std::string ToolChain::getDefaultUniversalArchName() const { // In universal driver terms, the arch name accepted by -arch isn't exactly // the same as the ones that appear in the triple. Roughly speaking, this is diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 7ca69ef285..aabcad3c8b 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -8,13 +8,13 @@ //===----------------------------------------------------------------------===// #include "ToolChains.h" -#include "SanitizerArgs.h" #include "clang/Basic/ObjCRuntime.h" #include "clang/Basic/Version.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" +#include "clang/Driver/SanitizerArgs.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" @@ -290,7 +290,7 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, } } - SanitizerArgs Sanitize(getDriver(), Args); + const SanitizerArgs &Sanitize = getDriver().getOrParseSanitizerArgs(Args); // Add Ubsan runtime library, if required. if (Sanitize.needsUbsanRt()) { @@ -2356,8 +2356,6 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) } addPathIfExists(SysRoot + "/lib", Paths); addPathIfExists(SysRoot + "/usr/lib", Paths); - - IsPIEDefault = SanitizerArgs(getDriver(), Args).hasZeroBaseShadow(*this); } bool Linux::HasNativeLLVMSupport() const { @@ -2609,7 +2607,7 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, } bool Linux::isPIEDefault() const { - return IsPIEDefault; + return getSanitizerArgs().hasZeroBaseShadow(*this); } /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index d1116b6233..a37cf472ff 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -569,7 +569,6 @@ public: std::string Linker; std::vector ExtraOpts; - bool IsPIEDefault; protected: virtual Tool *buildAssembler() const; diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 9768352ef9..ad004ba113 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -9,7 +9,6 @@ #include "Tools.h" #include "InputInfo.h" -#include "SanitizerArgs.h" #include "ToolChains.h" #include "clang/Basic/ObjCRuntime.h" #include "clang/Basic/Version.h" @@ -19,6 +18,7 @@ #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Job.h" #include "clang/Driver/Options.h" +#include "clang/Driver/SanitizerArgs.h" #include "clang/Driver/ToolChain.h" #include "clang/Driver/Util.h" #include "llvm/ADT/SmallString.h" @@ -2822,7 +2822,7 @@ 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(D, Args); + const SanitizerArgs &Sanitize = D.getOrParseSanitizerArgs(Args); Sanitize.addArgs(getToolChain(), Args, CmdArgs); if (!Args.hasFlag(options::OPT_fsanitize_recover, @@ -4795,7 +4795,8 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_L); - SanitizerArgs Sanitize(getToolChain().getDriver(), Args); + const SanitizerArgs &Sanitize = + getToolChain().getDriver().getOrParseSanitizerArgs(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 @@ -6059,7 +6060,7 @@ 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(D, Args); + const SanitizerArgs &Sanitize = D.getOrParseSanitizerArgs(Args); const bool IsPIE = !Args.hasArg(options::OPT_shared) && (Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow(ToolChain)); diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c index 2e9b5c883d..aaca33e405 100644 --- a/test/Driver/fsanitize.c +++ b/test/Driver/fsanitize.c @@ -145,3 +145,7 @@ // RUN: %clang -target x86_64-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN // CHECK-MSAN: "-fno-assume-sane-operator-new" + +// RUN: %clang -target x86_64-linux-gnu -fsanitize=zzz %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DIAG1 +// CHECK-DIAG1: unsupported argument 'zzz' to option 'fsanitize=' +// CHECK-DIAG1-NOT: unsupported argument 'zzz' to option 'fsanitize=' diff --git a/test/Driver/integrated-as.s b/test/Driver/integrated-as.s index 0a4b9b971b..11db4cf633 100644 --- a/test/Driver/integrated-as.s +++ b/test/Driver/integrated-as.s @@ -7,3 +7,6 @@ // RUN: not %clang -c -integrated-as -Wa,--compress-debug-sections %s 2>&1 | FileCheck --check-prefix=INVALID %s // INVALID: error: unsupported argument '--compress-debug-sections' to option 'Wa,' + +// RUN: %clang -### -c -integrated-as %s -fsanitize=address 2>&1 %s | FileCheck --check-prefix=SANITIZE %s +// SANITIZE: argument unused during compilation: '-fsanitize=address'