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

llvm-svn: 188660
This commit is contained in:
Alexey Samsonov 2013-08-19 09:14:21 +00:00
parent 88e024969b
commit 609213f9eb
11 changed files with 41 additions and 20 deletions

View File

@ -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<ToolChain *> ToolChains;
/// Parsed arguments passed to sanitizer tools.
mutable llvm::OwningPtr<SanitizerArgs> 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<unsigned, unsigned> 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.

View File

@ -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; }

View File

@ -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

View File

@ -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<unsigned, unsigned> 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();
}

View File

@ -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) {

View File

@ -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

View File

@ -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.

View File

@ -569,7 +569,6 @@ public:
std::string Linker;
std::vector<std::string> ExtraOpts;
bool IsPIEDefault;
protected:
virtual Tool *buildAssembler() const;

View File

@ -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));

View File

@ -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='

View File

@ -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'