Parse sanitizer arguments lazily, if a tool needs them. Add a test for this.
Hi rsmith,
http://llvm-reviews.chandlerc.com/D1341
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D1341?vs=3319&id=3418#toc
Files:
include/clang/Driver/ToolChain.h
include/clang/Driver/SanitizerArgs.h
include/clang/Driver/Driver.h
lib/Driver/ToolChain.cpp
lib/Driver/SanitizerArgs.cpp
lib/Driver/SanitizerArgs.h
lib/Driver/Driver.cpp
lib/Driver/Tools.cpp
lib/Driver/ToolChains.cpp
lib/Driver/ToolChains.h
test/Driver/fsanitize.c
test/Driver/integrated-as.s
Index: include/clang/Driver/ToolChain.h
===================================================================
--- include/clang/Driver/ToolChain.h
+++ include/clang/Driver/ToolChain.h
@@ -34,6 +34,7 @@
class Compilation;
class Driver;
class JobAction;
+ class SanitizerArgs;
class Tool;
/// ToolChain - Access to tools for a single platform.
@@ -124,6 +125,8 @@
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
Index: include/clang/Driver/SanitizerArgs.h
===================================================================
--- include/clang/Driver/SanitizerArgs.h
+++ include/clang/Driver/SanitizerArgs.h
@@ -59,8 +59,6 @@
/// 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; }
Index: include/clang/Driver/Driver.h
===================================================================
--- include/clang/Driver/Driver.h
+++ 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 @@
class Compilation;
class InputInfo;
class JobAction;
+ class SanitizerArgs;
class ToolChain;
/// Driver - Encapsulate logic for constructing compilation processes
@@ -177,6 +179,9 @@
/// 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 @@
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.
Index: lib/Driver/ToolChain.cpp
===================================================================
--- lib/Driver/ToolChain.cpp
+++ lib/Driver/ToolChain.cpp
@@ -42,6 +42,10 @@
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
Index: lib/Driver/SanitizerArgs.cpp
===================================================================
--- lib/Driver/SanitizerArgs.cpp
+++ 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 @@
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) {
Index: lib/Driver/SanitizerArgs.h
===================================================================
--- lib/Driver/SanitizerArgs.h
+++ lib/Driver/SanitizerArgs.h
@@ -1,129 +0,0 @@
-//===--- SanitizerArgs.h - Arguments for sanitizer tools -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef CLANG_LIB_DRIVER_SANITIZERARGS_H_
-#define CLANG_LIB_DRIVER_SANITIZERARGS_H_
-
-#include <string>
-
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/ArgList.h"
-
-namespace clang {
-namespace driver {
-
-class Driver;
-class ToolChain;
-
-class SanitizerArgs {
- /// Assign ordinals to sanitizer flags. We'll use the ordinal values as
- /// bit positions within \c Kind.
- enum SanitizeOrdinal {
-#define SANITIZER(NAME, ID) SO_##ID,
-#include "clang/Basic/Sanitizers.def"
- SO_Count
- };
-
- /// Bugs to catch at runtime.
- enum SanitizeKind {
-#define SANITIZER(NAME, ID) ID = 1 << SO_##ID,
-#define SANITIZER_GROUP(NAME, ID, ALIAS) ID = ALIAS,
-#include "clang/Basic/Sanitizers.def"
- NeedsAsanRt = Address,
- NeedsTsanRt = Thread,
- NeedsMsanRt = Memory,
- NeedsDfsanRt = DataFlow,
- NeedsLeakDetection = Leak,
- NeedsUbsanRt = Undefined | Integer,
- NotAllowedWithTrap = Vptr,
- HasZeroBaseShadow = Thread | Memory | DataFlow
- };
- unsigned Kind;
-
- std::string BlacklistFile;
- bool MsanTrackOrigins;
- 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 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; }
- bool needsLeakDetection() const { return Kind & NeedsLeakDetection; }
- bool needsLsanRt() const {
- return needsLeakDetection() && !needsAsanRt();
- }
- bool needsUbsanRt() const {
- return !UbsanTrapOnError && (Kind & NeedsUbsanRt);
- }
- bool needsDfsanRt() const { return Kind & NeedsDfsanRt; }
-
- bool sanitizesVptr() const { return Kind & Vptr; }
- bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; }
- bool hasZeroBaseShadow(const ToolChain &TC) const {
- return (Kind & HasZeroBaseShadow) || hasAsanZeroBaseShadow(TC);
- }
- 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.
- static unsigned parse(const char *Value);
-
- /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
- /// invalid components.
- static unsigned parse(const Driver &D, const llvm::opt::Arg *A,
- bool DiagnoseErrors);
-
- /// Parse a single flag of the form -f[no]sanitize=, or
- /// -f*-sanitizer. Sets the masks defining required change of Kind value.
- /// Returns true if the flag was parsed successfully.
- static bool parse(const Driver &D, const llvm::opt::ArgList &Args,
- const llvm::opt::Arg *A, unsigned &Add, unsigned &Remove,
- bool DiagnoseErrors);
-
- /// Produce an argument string from ArgList \p Args, which shows how it
- /// provides a sanitizer kind in \p Mask. For example, the argument list
- /// "-fsanitize=thread,vptr -faddress-sanitizer" with mask \c NeedsUbsanRt
- /// would produce "-fsanitize=vptr".
- static std::string lastArgumentForKind(const Driver &D,
- const llvm::opt::ArgList &Args,
- unsigned Kind);
-
- /// Produce an argument string from argument \p A, which shows how it provides
- /// a value in \p Mask. For instance, the argument
- /// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce
- /// "-fsanitize=alignment".
- static std::string describeSanitizeArg(const llvm::opt::ArgList &Args,
- const llvm::opt::Arg *A,
- unsigned Mask);
-
- static bool getDefaultBlacklistForKind(const Driver &D, unsigned Kind,
- std::string &BLPath);
-};
-
-} // namespace driver
-} // namespace clang
-
-#endif // CLANG_LIB_DRIVER_SANITIZERARGS_H_
Index: lib/Driver/Driver.cpp
===================================================================
--- lib/Driver/Driver.cpp
+++ 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"
@@ -2037,3 +2038,10 @@
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();
+}
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ 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"
@@ -2777,7 +2777,7 @@
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,
@@ -4750,7 +4750,8 @@
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
@@ -6014,7 +6015,7 @@
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));
Index: lib/Driver/ToolChains.cpp
===================================================================
--- lib/Driver/ToolChains.cpp
+++ 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 @@
}
}
- SanitizerArgs Sanitize(getDriver(), Args);
+ const SanitizerArgs &Sanitize = getDriver().getOrParseSanitizerArgs(Args);
// Add Ubsan runtime library, if required.
if (Sanitize.needsUbsanRt()) {
@@ -2354,8 +2354,6 @@
}
addPathIfExists(SysRoot + "/lib", Paths);
addPathIfExists(SysRoot + "/usr/lib", Paths);
-
- IsPIEDefault = SanitizerArgs(getDriver(), Args).hasZeroBaseShadow(*this);
}
bool Linux::HasNativeLLVMSupport() const {
@@ -2607,7 +2605,7 @@
}
bool Linux::isPIEDefault() const {
- return IsPIEDefault;
+ return getSanitizerArgs().hasZeroBaseShadow(*this);
}
/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
Index: lib/Driver/ToolChains.h
===================================================================
--- lib/Driver/ToolChains.h
+++ lib/Driver/ToolChains.h
@@ -561,7 +561,6 @@
std::string Linker;
std::vector<std::string> ExtraOpts;
- bool IsPIEDefault;
protected:
virtual Tool *buildAssembler() const;
Index: test/Driver/fsanitize.c
===================================================================
--- test/Driver/fsanitize.c
+++ 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='
Index: test/Driver/integrated-as.s
===================================================================
--- test/Driver/integrated-as.s
+++ 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'
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits