diff options
author | Alexey Samsonov <samsonov@google.com> | 2012-11-06 15:09:03 +0000 |
---|---|---|
committer | Alexey Samsonov <samsonov@google.com> | 2012-11-06 15:09:03 +0000 |
commit | bb1071c0568db9bd7934e869a53d671632eb9291 (patch) | |
tree | 53a870600e149441991103c2418a4b2e7bd11b05 /lib/Driver/Tools.cpp | |
parent | 3d615b2a4217200fe1226d77683f4ef57dffbffd (diff) |
Follow-up for r167411 to un-break ASan on Mac. Move SanitizerArgs to a header file and use it on Darwin toolchain.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167460 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Driver/Tools.cpp')
-rw-r--r-- | lib/Driver/Tools.cpp | 139 |
1 files changed, 26 insertions, 113 deletions
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 973df104d5..2eca3fe7b7 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -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 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) { 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 @@ static SanitizerArgs getSanitizerArgs(const Driver &D, const ArgList &Args) { // 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 @@ 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 = 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 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, 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 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, 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 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA, 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()) |