[cfe-commits] r167460 - in /cfe/trunk/lib/Driver: SanitizerArgs.h ToolChains.cpp Tools.cpp
Alexey Samsonov
samsonov at google.com
Tue Nov 6 07:09:03 PST 2012
Author: samsonov
Date: Tue Nov 6 09:09:03 2012
New Revision: 167460
URL: http://llvm.org/viewvc/llvm-project?rev=167460&view=rev
Log:
Follow-up for r167411 to un-break ASan on Mac. Move SanitizerArgs to a header file and use it on Darwin toolchain.
Added:
cfe/trunk/lib/Driver/SanitizerArgs.h
Modified:
cfe/trunk/lib/Driver/ToolChains.cpp
cfe/trunk/lib/Driver/Tools.cpp
Added: cfe/trunk/lib/Driver/SanitizerArgs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/SanitizerArgs.h?rev=167460&view=auto
==============================================================================
--- cfe/trunk/lib/Driver/SanitizerArgs.h (added)
+++ cfe/trunk/lib/Driver/SanitizerArgs.h Tue Nov 6 09:09:03 2012
@@ -0,0 +1,106 @@
+//===--- 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 "clang/Driver/ArgList.h"
+
+namespace clang {
+namespace driver {
+
+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,
+ NeedsUbsanRt = Undefined
+ };
+ unsigned Kind;
+
+ public:
+ SanitizerArgs() : Kind(0) {}
+ /// Parses the sanitizer arguments from an argument list.
+ SanitizerArgs(const Driver &D, const ArgList &Args);
+
+ bool needsAsanRt() const { return Kind & NeedsAsanRt; }
+ bool needsTsanRt() const { return Kind & NeedsTsanRt; }
+ bool needsUbsanRt() const { return Kind & NeedsUbsanRt; }
+
+ bool sanitizesVptr() const { return Kind & Vptr; }
+
+ void addArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
+ if (!Kind)
+ return;
+ llvm::SmallString<256> SanitizeOpt("-fsanitize=");
+#define SANITIZER(NAME, ID) \
+ if (Kind & ID) \
+ SanitizeOpt += NAME ",";
+#include "clang/Basic/Sanitizers.def"
+ SanitizeOpt.pop_back();
+ CmdArgs.push_back(Args.MakeArgString(SanitizeOpt));
+ }
+
+ private:
+ /// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
+ /// Returns a member of the \c SanitizeKind enumeration, or \c 0 if \p Value
+ /// is not known.
+ static unsigned parse(const char *Value) {
+ return llvm::StringSwitch<SanitizeKind>(Value)
+#define SANITIZER(NAME, ID) .Case(NAME, ID)
+#define SANITIZER_GROUP(NAME, ID, ALIAS) .Case(NAME, ID)
+#include "clang/Basic/Sanitizers.def"
+ .Default(SanitizeKind());
+ }
+
+ /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
+ /// invalid components.
+ static unsigned parse(const Driver &D, const Arg *A) {
+ unsigned Kind = 0;
+ for (unsigned I = 0, N = A->getNumValues(); I != N; ++I) {
+ if (unsigned K = parse(A->getValue(I)))
+ Kind |= K;
+ else
+ D.Diag(diag::err_drv_unsupported_option_argument)
+ << A->getOption().getName() << A->getValue(I);
+ }
+ return 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 ArgList &Args, const Arg *A,
+ unsigned Mask) {
+ if (!A->getOption().matches(options::OPT_fsanitize_EQ))
+ return A->getAsString(Args);
+
+ for (unsigned I = 0, N = A->getNumValues(); I != N; ++I)
+ if (parse(A->getValue(I)) & Mask)
+ return std::string("-fsanitize=") + A->getValue(I);
+
+ llvm_unreachable("arg didn't provide expected value");
+ }
+};
+
+} // namespace driver
+} // namespace clang
+
+#endif // CLANG_LIB_DRIVER_SANITIZERARGS_H_
Modified: cfe/trunk/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=167460&r1=167459&r2=167460&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains.cpp Tue Nov 6 09:09:03 2012
@@ -31,6 +31,8 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/system_error.h"
+#include "SanitizerArgs.h"
+
#include <cstdlib> // ::getenv
#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
@@ -359,15 +361,16 @@
}
}
+ SanitizerArgs Sanitize(getDriver(), Args);
+
// Add ASAN runtime library, if required. Dynamic libraries and bundles
// should not be linked with the runtime library.
- if (Args.hasFlag(options::OPT_faddress_sanitizer,
- options::OPT_fno_address_sanitizer, false)) {
+ if (Sanitize.needsAsanRt()) {
if (Args.hasArg(options::OPT_dynamiclib) ||
Args.hasArg(options::OPT_bundle)) return;
if (isTargetIPhoneOS()) {
getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
- << "-faddress-sanitizer";
+ << "-fsanitize=address";
} else {
AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.asan_osx.a");
Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=167460&r1=167459&r2=167460&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Tue Nov 6 09:09:03 2012
@@ -33,6 +33,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "InputInfo.h"
+#include "SanitizerArgs.h"
#include "ToolChains.h"
using namespace clang::driver;
@@ -1452,128 +1453,44 @@
RelaxDefault);
}
-namespace {
-struct 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,
- NeedsUbsanRt = Undefined
- };
- unsigned Kind;
-
- SanitizerArgs() : Kind(0) {}
-
- bool needsAsanRt() const { return Kind & NeedsAsanRt; }
- bool needsTsanRt() const { return Kind & NeedsTsanRt; }
- bool needsUbsanRt() const { return Kind & NeedsUbsanRt; }
-
- /// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
- /// Returns a member of the \c SanitizeKind enumeration, or \c 0 if \p Value
- /// is not known.
- static unsigned parse(const char *Value) {
- return llvm::StringSwitch<SanitizeKind>(Value)
-#define SANITIZER(NAME, ID) .Case(NAME, ID)
-#define SANITIZER_GROUP(NAME, ID, ALIAS) .Case(NAME, ID)
-#include "clang/Basic/Sanitizers.def"
- .Default(SanitizeKind());
- }
-
- /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
- /// invalid components.
- static unsigned parse(const Driver &D, const Arg *A) {
- unsigned Kind = 0;
- for (unsigned I = 0, N = A->getNumValues(); I != N; ++I) {
- if (unsigned K = parse(A->getValue(I)))
- Kind |= K;
- else
- D.Diag(diag::err_drv_unsupported_option_argument)
- << A->getOption().getName() << A->getValue(I);
- }
- return Kind;
- }
-
- void addArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
- if (!Kind)
- return;
- llvm::SmallString<256> SanitizeOpt("-fsanitize=");
-#define SANITIZER(NAME, ID) \
- if (Kind & ID) \
- SanitizeOpt += NAME ",";
-#include "clang/Basic/Sanitizers.def"
- SanitizeOpt.pop_back();
- CmdArgs.push_back(Args.MakeArgString(SanitizeOpt));
- }
-};
-}
-
-/// 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 ArgList &Args, const Arg *A,
- unsigned Mask) {
- if (!A->getOption().matches(options::OPT_fsanitize_EQ))
- return A->getAsString(Args);
-
- for (unsigned I = 0, N = A->getNumValues(); I != N; ++I)
- if (SanitizerArgs::parse(A->getValue(I)) & Mask)
- return std::string("-fsanitize=") + A->getValue(I);
-
- llvm_unreachable("arg didn't provide expected value");
-}
-
-/// Parse the sanitizer arguments from an argument list.
-static SanitizerArgs getSanitizerArgs(const Driver &D, const ArgList &Args) {
- SanitizerArgs Sanitize;
+SanitizerArgs::SanitizerArgs(const Driver &D, const ArgList &Args) {
+ Kind = 0;
const Arg *AsanArg, *TsanArg, *UbsanArg;
-
for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) {
unsigned Add = 0, Remove = 0;
const char *DeprecatedReplacement = 0;
if ((*I)->getOption().matches(options::OPT_faddress_sanitizer)) {
- Add = SanitizerArgs::Address;
+ Add = Address;
DeprecatedReplacement = "-fsanitize=address";
} else if ((*I)->getOption().matches(options::OPT_fno_address_sanitizer)) {
- Remove = SanitizerArgs::Address;
+ Remove = Address;
DeprecatedReplacement = "-fno-sanitize=address";
} else if ((*I)->getOption().matches(options::OPT_fthread_sanitizer)) {
- Add = SanitizerArgs::Thread;
+ Add = Thread;
DeprecatedReplacement = "-fsanitize=thread";
} else if ((*I)->getOption().matches(options::OPT_fno_thread_sanitizer)) {
- Remove = SanitizerArgs::Thread;
+ Remove = Thread;
DeprecatedReplacement = "-fno-sanitize=thread";
} else if ((*I)->getOption().matches(options::OPT_fcatch_undefined_behavior)) {
- Add = SanitizerArgs::Undefined;
+ Add = Undefined;
DeprecatedReplacement = "-fsanitize=undefined";
} else if ((*I)->getOption().matches(options::OPT_fsanitize_EQ)) {
- Add = SanitizerArgs::parse(D, *I);
+ Add = parse(D, *I);
} else if ((*I)->getOption().matches(options::OPT_fno_sanitize_EQ)) {
- Remove = SanitizerArgs::parse(D, *I);
+ Remove = parse(D, *I);
} else {
continue;
}
(*I)->claim();
- Sanitize.Kind |= Add;
- Sanitize.Kind &= ~Remove;
+ Kind |= Add;
+ Kind &= ~Remove;
- if (Add & SanitizerArgs::NeedsAsanRt) AsanArg = *I;
- if (Add & SanitizerArgs::NeedsTsanRt) TsanArg = *I;
- if (Add & SanitizerArgs::NeedsUbsanRt) UbsanArg = *I;
+ if (Add & NeedsAsanRt) AsanArg = *I;
+ if (Add & NeedsTsanRt) TsanArg = *I;
+ if (Add & NeedsUbsanRt) UbsanArg = *I;
// If this is a deprecated synonym, produce a warning directing users
// towards the new spelling.
@@ -1584,19 +1501,15 @@
// Only one runtime library can be used at once.
// FIXME: Allow Ubsan to be combined with the other two.
- bool NeedsAsan = Sanitize.needsAsanRt();
- bool NeedsTsan = Sanitize.needsTsanRt();
- bool NeedsUbsan = Sanitize.needsUbsanRt();
+ bool NeedsAsan = needsAsanRt();
+ bool NeedsTsan = needsTsanRt();
+ bool NeedsUbsan = needsUbsanRt();
if (NeedsAsan + NeedsTsan + NeedsUbsan > 1)
D.Diag(diag::err_drv_argument_not_allowed_with)
<< describeSanitizeArg(Args, NeedsAsan ? AsanArg : TsanArg,
- NeedsAsan ? SanitizerArgs::NeedsAsanRt
- : SanitizerArgs::NeedsTsanRt)
+ NeedsAsan ? NeedsAsanRt : NeedsTsanRt)
<< describeSanitizeArg(Args, NeedsUbsan ? UbsanArg : TsanArg,
- NeedsUbsan ? SanitizerArgs::NeedsUbsanRt
- : SanitizerArgs::NeedsTsanRt);
-
- return Sanitize;
+ NeedsUbsan ? NeedsUbsanRt : NeedsTsanRt);
}
/// If AddressSanitizer is enabled, add appropriate linker flags (Linux).
@@ -2518,7 +2431,7 @@
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
- SanitizerArgs Sanitize = getSanitizerArgs(D, Args);
+ SanitizerArgs Sanitize(D, Args);
Sanitize.addArgs(Args, CmdArgs);
// Report and error for -faltivec on anything other then PowerPC.
@@ -2681,7 +2594,7 @@
CmdArgs.push_back("-fno-rtti");
// -fno-rtti cannot usefully be combined with -fsanitize=vptr.
- if (Sanitize.Kind & SanitizerArgs::Vptr) {
+ if (Sanitize.sanitizesVptr()) {
llvm::StringRef NoRttiArg =
Args.getLastArg(options::OPT_mkernel,
options::OPT_fapple_kext,
@@ -4768,11 +4681,11 @@
Args.AddAllArgs(CmdArgs, options::OPT_L);
- // If we're building a dynamic lib with -faddress-sanitizer, unresolved
+ 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 lib/Driver/ToolChains.cpp.
- if (Args.hasFlag(options::OPT_faddress_sanitizer,
- options::OPT_fno_address_sanitizer, false)) {
+ if (Sanitize.needsAsanRt()) {
if (Args.hasArg(options::OPT_dynamiclib) ||
Args.hasArg(options::OPT_bundle)) {
CmdArgs.push_back("-undefined");
@@ -6116,7 +6029,7 @@
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
- SanitizerArgs Sanitize = getSanitizerArgs(D, Args);
+ SanitizerArgs Sanitize(D, Args);
// Call this before we add the C++ ABI library.
if (Sanitize.needsUbsanRt())
More information about the cfe-commits
mailing list