Hi rsmith,
This change turns SanitizerArgs into high-level options
stored in the Driver. Now they are parsed exactly once in
BuildCompilation function. This fixes an issue of multiple copies
of the same diagnostic message produced by sanitizer arguments parser.
http://llvm-reviews.chandlerc.com/D1341
Files:
lib/Driver/ToolChains.cpp
lib/Driver/SanitizerArgs.cpp
lib/Driver/SanitizerArgs.h
lib/Driver/Driver.cpp
lib/Driver/Tools.cpp
test/Driver/fsanitize.c
include/clang/Driver/SanitizerArgs.h
include/clang/Driver/Driver.h
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().SanitizerArguments;
// Add Ubsan runtime library, if required.
if (Sanitize.needsUbsanRt()) {
@@ -2354,7 +2354,7 @@
addPathIfExists(SysRoot + "/lib", Paths);
addPathIfExists(SysRoot + "/usr/lib", Paths);
- IsPIEDefault = SanitizerArgs(getDriver(), Args).hasZeroBaseShadow(*this);
+ IsPIEDefault = getDriver().SanitizerArguments.hasZeroBaseShadow(*this);
}
bool Linux::HasNativeLLVMSupport() const {
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,9 @@
clear();
}
-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) {
+ clear();
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
@@ -335,6 +335,8 @@
if (const Arg *A = Args->getLastArg(options::OPT_resource_dir))
ResourceDir = A->getValue();
+ SanitizerArguments.parse(*this, *Args);
+
// Perform the default argument translations.
DerivedArgList *TranslatedArgs = TranslateInputArgs(*Args);
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"
@@ -2792,7 +2792,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.SanitizerArguments;
Sanitize.addArgs(getToolChain(), Args, CmdArgs);
if (!Args.hasFlag(options::OPT_fsanitize_recover,
@@ -4765,7 +4765,7 @@
Args.AddAllArgs(CmdArgs, options::OPT_L);
- SanitizerArgs Sanitize(getToolChain().getDriver(), Args);
+ const SanitizerArgs &Sanitize = getToolChain().getDriver().SanitizerArguments;
// 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,7 +6029,7 @@
const Driver &D = ToolChain.getDriver();
const bool isAndroid =
ToolChain.getTriple().getEnvironment() == llvm::Triple::Android;
- SanitizerArgs Sanitize(D, Args);
+ const SanitizerArgs &Sanitize = D.SanitizerArguments;
const bool IsPIE =
!Args.hasArg(options::OPT_shared) &&
(Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow(ToolChain));
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: include/clang/Driver/SanitizerArgs.h
===================================================================
--- include/clang/Driver/SanitizerArgs.h
+++ include/clang/Driver/SanitizerArgs.h
@@ -56,9 +56,8 @@
public:
SanitizerArgs();
- /// Parses the sanitizer arguments from an argument list.
- SanitizerArgs(const Driver &D, const llvm::opt::ArgList &Args);
+ /// Parses the sanitizer arguments from an argument list.
void parse(const Driver &D, const llvm::opt::ArgList &Args);
bool needsAsanRt() const { return Kind & NeedsAsanRt; }
Index: include/clang/Driver/Driver.h
===================================================================
--- include/clang/Driver/Driver.h
+++ include/clang/Driver/Driver.h
@@ -13,6 +13,7 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
#include "clang/Driver/Phases.h"
+#include "clang/Driver/SanitizerArgs.h"
#include "clang/Driver/Types.h"
#include "clang/Driver/Util.h"
#include "llvm/ADT/StringMap.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,10 @@
/// stored in it, and will clean them up when torn down.
mutable llvm::StringMap<ToolChain *> ToolChains;
+public:
+ /// Parsed arguments passed to sanitizer tools.
+ SanitizerArgs SanitizerArguments;
+
private:
/// TranslateInputArgs - Create a new derived argument list from the input
/// arguments, after applying the standard argument translations.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits