forked from OSchip/llvm-project
SanitizerArgs: add ability to filter/diagnose unsupported sanitizers.
The thread, memory, dataflow and function sanitizers are now diagnosed if enabled explicitly on an unsupported platform. Unsupported sanitizers which are enabled implicitly (as part of a larger group) are silently disabled. As a side effect, this makes SanitizerArgs parsing toolchain-dependent (and thus essentially reverts r188058), and moves SanitizerArgs ownership to ToolChain. Differential Revision: http://llvm-reviews.chandlerc.com/D1990 llvm-svn: 193875
This commit is contained in:
parent
1d0b6bb2ef
commit
3270164f39
|
@ -179,9 +179,6 @@ 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.
|
||||
|
@ -406,10 +403,6 @@ 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.
|
||||
|
|
|
@ -25,6 +25,7 @@ class SanitizerArgs {
|
|||
/// bit positions within \c Kind.
|
||||
enum SanitizeOrdinal {
|
||||
#define SANITIZER(NAME, ID) SO_##ID,
|
||||
#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group,
|
||||
#include "clang/Basic/Sanitizers.def"
|
||||
SO_Count
|
||||
};
|
||||
|
@ -32,7 +33,8 @@ class SanitizerArgs {
|
|||
/// Bugs to catch at runtime.
|
||||
enum SanitizeKind {
|
||||
#define SANITIZER(NAME, ID) ID = 1 << SO_##ID,
|
||||
#define SANITIZER_GROUP(NAME, ID, ALIAS) ID = ALIAS,
|
||||
#define SANITIZER_GROUP(NAME, ID, ALIAS) \
|
||||
ID = ALIAS, ID##Group = 1 << SO_##ID##Group,
|
||||
#include "clang/Basic/Sanitizers.def"
|
||||
NeedsAsanRt = Address,
|
||||
NeedsTsanRt = Thread,
|
||||
|
@ -47,17 +49,13 @@ class SanitizerArgs {
|
|||
|
||||
std::string BlacklistFile;
|
||||
bool MsanTrackOrigins;
|
||||
enum AsanZeroBaseShadowKind {
|
||||
AZBSK_Default, // Default value is toolchain-specific.
|
||||
AZBSK_On,
|
||||
AZBSK_Off
|
||||
} AsanZeroBaseShadow;
|
||||
bool AsanZeroBaseShadow;
|
||||
bool UbsanTrapOnError;
|
||||
|
||||
public:
|
||||
SanitizerArgs();
|
||||
/// Parses the sanitizer arguments from an argument list.
|
||||
SanitizerArgs(const Driver &D, const llvm::opt::ArgList &Args);
|
||||
SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
|
||||
|
||||
bool needsAsanRt() const { return Kind & NeedsAsanRt; }
|
||||
bool needsTsanRt() const { return Kind & NeedsTsanRt; }
|
||||
|
@ -73,17 +71,15 @@ class SanitizerArgs {
|
|||
|
||||
bool sanitizesVptr() const { return Kind & Vptr; }
|
||||
bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; }
|
||||
bool hasZeroBaseShadow(const ToolChain &TC) const {
|
||||
return (Kind & HasZeroBaseShadow) || hasAsanZeroBaseShadow(TC);
|
||||
bool hasZeroBaseShadow() const {
|
||||
return (Kind & HasZeroBaseShadow) || AsanZeroBaseShadow;
|
||||
}
|
||||
void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
|
||||
void addArgs(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.
|
||||
|
@ -119,6 +115,30 @@ class SanitizerArgs {
|
|||
|
||||
static bool getDefaultBlacklistForKind(const Driver &D, unsigned Kind,
|
||||
std::string &BLPath);
|
||||
|
||||
/// Return the smallest superset of sanitizer set \p Kinds such that each
|
||||
/// member of each group whose flag is set in \p Kinds has its flag set in the
|
||||
/// result.
|
||||
static unsigned expandGroups(unsigned Kinds);
|
||||
|
||||
/// Return the subset of \p Kinds supported by toolchain \p TC. If
|
||||
/// \p DiagnoseErrors is true, produce an error diagnostic for each sanitizer
|
||||
/// removed from \p Kinds.
|
||||
static unsigned filterUnsupportedKinds(const ToolChain &TC, unsigned Kinds,
|
||||
const llvm::opt::ArgList &Args,
|
||||
const llvm::opt::Arg *A,
|
||||
bool DiagnoseErrors,
|
||||
unsigned &DiagnosedKinds);
|
||||
|
||||
/// The flags in \p Mask are unsupported by \p TC. If present in \p Kinds,
|
||||
/// remove them and produce an error diagnostic referring to \p A if
|
||||
/// \p DiagnoseErrors is true.
|
||||
static void filterUnsupportedMask(const ToolChain &TC, unsigned &Kinds,
|
||||
unsigned Mask,
|
||||
const llvm::opt::ArgList &Args,
|
||||
const llvm::opt::Arg *A,
|
||||
bool DiagnoseErrors,
|
||||
unsigned &DiagnosedKinds);
|
||||
};
|
||||
|
||||
} // namespace driver
|
||||
|
|
|
@ -73,6 +73,8 @@ private:
|
|||
Tool *getLink() const;
|
||||
Tool *getClangAs() const;
|
||||
|
||||
mutable OwningPtr<SanitizerArgs> SanitizerArguments;
|
||||
|
||||
protected:
|
||||
ToolChain(const Driver &D, const llvm::Triple &T,
|
||||
const llvm::opt::ArgList &Args);
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#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"
|
||||
|
@ -2056,10 +2055,3 @@ 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();
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ void SanitizerArgs::clear() {
|
|||
Kind = 0;
|
||||
BlacklistFile = "";
|
||||
MsanTrackOrigins = false;
|
||||
AsanZeroBaseShadow = AZBSK_Default;
|
||||
AsanZeroBaseShadow = false;
|
||||
UbsanTrapOnError = false;
|
||||
}
|
||||
|
||||
|
@ -33,18 +33,42 @@ SanitizerArgs::SanitizerArgs() {
|
|||
clear();
|
||||
}
|
||||
|
||||
SanitizerArgs::SanitizerArgs(const Driver &D, const llvm::opt::ArgList &Args) {
|
||||
SanitizerArgs::SanitizerArgs(const ToolChain &TC,
|
||||
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) {
|
||||
unsigned AllAdd = 0; // All kinds of sanitizers that were turned on
|
||||
// at least once (possibly, disabled further).
|
||||
unsigned AllRemove = 0; // During the loop below, the accumulated set of
|
||||
// sanitizers disabled by the current sanitizer
|
||||
// argument or any argument after it.
|
||||
unsigned DiagnosedKinds = 0; // All Kinds we have diagnosed up to now.
|
||||
// Used to deduplicate diagnostics.
|
||||
const Driver &D = TC.getDriver();
|
||||
for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
|
||||
I != E; ++I) {
|
||||
unsigned Add, Remove;
|
||||
if (!parse(D, Args, *I, Add, Remove, true))
|
||||
continue;
|
||||
(*I)->claim();
|
||||
|
||||
AllAdd |= expandGroups(Add);
|
||||
AllRemove |= expandGroups(Remove);
|
||||
|
||||
// Avoid diagnosing any sanitizer which is disabled later.
|
||||
Add &= ~AllRemove;
|
||||
// At this point we have not expanded groups, so any unsupported sanitizers
|
||||
// in Add are those which have been explicitly enabled. Diagnose them.
|
||||
Add = filterUnsupportedKinds(TC, Add, Args, *I, /*DiagnoseErrors=*/true,
|
||||
DiagnosedKinds);
|
||||
Add = expandGroups(Add);
|
||||
// Group expansion may have enabled a sanitizer which is disabled later.
|
||||
Add &= ~AllRemove;
|
||||
// Silently discard any unsupported sanitizers implicitly enabled through
|
||||
// group expansion.
|
||||
Add = filterUnsupportedKinds(TC, Add, Args, *I, /*DiagnoseErrors=*/false,
|
||||
DiagnosedKinds);
|
||||
|
||||
Kind |= Add;
|
||||
Kind &= ~Remove;
|
||||
AllKinds |= Add;
|
||||
}
|
||||
|
||||
UbsanTrapOnError =
|
||||
|
@ -107,7 +131,7 @@ SanitizerArgs::SanitizerArgs(const Driver &D, const llvm::opt::ArgList &Args) {
|
|||
// If -fsanitize contains extra features of ASan, it should also
|
||||
// explicitly contain -fsanitize=address (probably, turned off later in the
|
||||
// command line).
|
||||
if ((Kind & AddressFull) != 0 && (AllKinds & Address) == 0)
|
||||
if ((Kind & AddressFull) != 0 && (AllAdd & Address) == 0)
|
||||
D.Diag(diag::warn_drv_unused_sanitizer)
|
||||
<< lastArgumentForKind(D, Args, AddressFull)
|
||||
<< "-fsanitize=address";
|
||||
|
@ -148,21 +172,25 @@ SanitizerArgs::SanitizerArgs(const Driver &D, const llvm::opt::ArgList &Args) {
|
|||
|
||||
// Parse -f(no-)sanitize-address-zero-base-shadow options.
|
||||
if (NeedsAsan) {
|
||||
if (Arg *A = Args.getLastArg(
|
||||
options::OPT_fsanitize_address_zero_base_shadow,
|
||||
options::OPT_fno_sanitize_address_zero_base_shadow))
|
||||
AsanZeroBaseShadow = A->getOption().matches(
|
||||
options::OPT_fsanitize_address_zero_base_shadow)
|
||||
? AZBSK_On
|
||||
: AZBSK_Off;
|
||||
bool IsAndroid = (TC.getTriple().getEnvironment() == llvm::Triple::Android);
|
||||
bool ZeroBaseShadowDefault = IsAndroid;
|
||||
AsanZeroBaseShadow =
|
||||
Args.hasFlag(options::OPT_fsanitize_address_zero_base_shadow,
|
||||
options::OPT_fno_sanitize_address_zero_base_shadow,
|
||||
ZeroBaseShadowDefault);
|
||||
// Zero-base shadow is a requirement on Android.
|
||||
if (IsAndroid && !AsanZeroBaseShadow) {
|
||||
D.Diag(diag::err_drv_argument_not_allowed_with)
|
||||
<< "-fno-sanitize-address-zero-base-shadow"
|
||||
<< lastArgumentForKind(D, Args, Address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
|
||||
void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args,
|
||||
llvm::opt::ArgStringList &CmdArgs) const {
|
||||
if (!Kind)
|
||||
return;
|
||||
const Driver &D = TC.getDriver();
|
||||
SmallString<256> SanitizeOpt("-fsanitize=");
|
||||
#define SANITIZER(NAME, ID) \
|
||||
if (Kind & ID) \
|
||||
|
@ -179,36 +207,19 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
|
|||
if (MsanTrackOrigins)
|
||||
CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins"));
|
||||
|
||||
if (needsAsanRt()) {
|
||||
if (hasAsanZeroBaseShadow(TC)) {
|
||||
CmdArgs.push_back(
|
||||
Args.MakeArgString("-fsanitize-address-zero-base-shadow"));
|
||||
} else if (TC.getTriple().getEnvironment() == llvm::Triple::Android) {
|
||||
// Zero-base shadow is a requirement on Android.
|
||||
D.Diag(diag::err_drv_argument_not_allowed_with)
|
||||
<< "-fno-sanitize-address-zero-base-shadow"
|
||||
<< lastArgumentForKind(D, Args, Address);
|
||||
}
|
||||
}
|
||||
if (AsanZeroBaseShadow)
|
||||
CmdArgs.push_back(
|
||||
Args.MakeArgString("-fsanitize-address-zero-base-shadow"));
|
||||
|
||||
// Workaround for PR16386.
|
||||
if (needsMsanRt())
|
||||
CmdArgs.push_back(Args.MakeArgString("-fno-assume-sane-operator-new"));
|
||||
}
|
||||
|
||||
bool SanitizerArgs::hasAsanZeroBaseShadow(const ToolChain &TC) const {
|
||||
if (!needsAsanRt())
|
||||
return false;
|
||||
if (AsanZeroBaseShadow != AZBSK_Default)
|
||||
return AsanZeroBaseShadow == AZBSK_On;
|
||||
// Zero-base shadow is used by default only on Android.
|
||||
return TC.getTriple().getEnvironment() == llvm::Triple::Android;
|
||||
}
|
||||
|
||||
unsigned SanitizerArgs::parse(const char *Value) {
|
||||
unsigned ParsedKind = llvm::StringSwitch<SanitizeKind>(Value)
|
||||
#define SANITIZER(NAME, ID) .Case(NAME, ID)
|
||||
#define SANITIZER_GROUP(NAME, ID, ALIAS) .Case(NAME, ID)
|
||||
#define SANITIZER_GROUP(NAME, ID, ALIAS) .Case(NAME, ID##Group)
|
||||
#include "clang/Basic/Sanitizers.def"
|
||||
.Default(SanitizeKind());
|
||||
// Assume -fsanitize=address implies -fsanitize=init-order,use-after-return.
|
||||
|
@ -219,6 +230,54 @@ unsigned SanitizerArgs::parse(const char *Value) {
|
|||
return ParsedKind;
|
||||
}
|
||||
|
||||
unsigned SanitizerArgs::expandGroups(unsigned Kinds) {
|
||||
#define SANITIZER(NAME, ID)
|
||||
#define SANITIZER_GROUP(NAME, ID, ALIAS) if (Kinds & ID##Group) Kinds |= ID;
|
||||
#include "clang/Basic/Sanitizers.def"
|
||||
return Kinds;
|
||||
}
|
||||
|
||||
void SanitizerArgs::filterUnsupportedMask(const ToolChain &TC, unsigned &Kinds,
|
||||
unsigned Mask,
|
||||
const llvm::opt::ArgList &Args,
|
||||
const llvm::opt::Arg *A,
|
||||
bool DiagnoseErrors,
|
||||
unsigned &DiagnosedKinds) {
|
||||
unsigned MaskedKinds = Kinds & Mask;
|
||||
if (!MaskedKinds)
|
||||
return;
|
||||
Kinds &= ~Mask;
|
||||
// Do we have new kinds to diagnose?
|
||||
if (DiagnoseErrors && (DiagnosedKinds & MaskedKinds) != MaskedKinds) {
|
||||
// Only diagnose the new kinds.
|
||||
std::string Desc =
|
||||
describeSanitizeArg(Args, A, MaskedKinds & ~DiagnosedKinds);
|
||||
TC.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
|
||||
<< Desc << TC.getTriple().str();
|
||||
DiagnosedKinds |= MaskedKinds;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned SanitizerArgs::filterUnsupportedKinds(const ToolChain &TC,
|
||||
unsigned Kinds,
|
||||
const llvm::opt::ArgList &Args,
|
||||
const llvm::opt::Arg *A,
|
||||
bool DiagnoseErrors,
|
||||
unsigned &DiagnosedKinds) {
|
||||
bool IsLinux = TC.getTriple().getOS() == llvm::Triple::Linux;
|
||||
bool IsX86 = TC.getTriple().getArch() == llvm::Triple::x86;
|
||||
bool IsX86_64 = TC.getTriple().getArch() == llvm::Triple::x86_64;
|
||||
if (!(IsLinux && IsX86_64)) {
|
||||
filterUnsupportedMask(TC, Kinds, Thread | Memory | DataFlow, Args, A,
|
||||
DiagnoseErrors, DiagnosedKinds);
|
||||
}
|
||||
if (!(IsLinux && (IsX86 || IsX86_64))) {
|
||||
filterUnsupportedMask(TC, Kinds, Function, Args, A, DiagnoseErrors,
|
||||
DiagnosedKinds);
|
||||
}
|
||||
return Kinds;
|
||||
}
|
||||
|
||||
unsigned SanitizerArgs::parse(const Driver &D, const llvm::opt::Arg *A,
|
||||
bool DiagnoseErrors) {
|
||||
unsigned Kind = 0;
|
||||
|
@ -282,7 +341,7 @@ std::string SanitizerArgs::lastArgumentForKind(const Driver &D,
|
|||
I != E; ++I) {
|
||||
unsigned Add, Remove;
|
||||
if (parse(D, Args, *I, Add, Remove, false) &&
|
||||
(Add & Kind))
|
||||
(expandGroups(Add) & Kind))
|
||||
return describeSanitizeArg(Args, *I, Kind);
|
||||
Kind &= ~Remove;
|
||||
}
|
||||
|
@ -295,11 +354,17 @@ std::string SanitizerArgs::describeSanitizeArg(const llvm::opt::ArgList &Args,
|
|||
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);
|
||||
std::string Sanitizers;
|
||||
for (unsigned I = 0, N = A->getNumValues(); I != N; ++I) {
|
||||
if (expandGroups(parse(A->getValue(I))) & Mask) {
|
||||
if (!Sanitizers.empty())
|
||||
Sanitizers += ",";
|
||||
Sanitizers += A->getValue(I);
|
||||
}
|
||||
}
|
||||
|
||||
llvm_unreachable("arg didn't provide expected value");
|
||||
assert(!Sanitizers.empty() && "arg didn't provide expected value");
|
||||
return "-fsanitize=" + Sanitizers;
|
||||
}
|
||||
|
||||
bool SanitizerArgs::getDefaultBlacklistForKind(const Driver &D, unsigned Kind,
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Driver/DriverDiagnostic.h"
|
||||
#include "clang/Driver/Options.h"
|
||||
#include "clang/Driver/SanitizerArgs.h"
|
||||
#include "clang/Driver/ToolChain.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Option/Arg.h"
|
||||
|
@ -43,7 +44,9 @@ bool ToolChain::useIntegratedAs() const {
|
|||
}
|
||||
|
||||
const SanitizerArgs& ToolChain::getSanitizerArgs() const {
|
||||
return D.getOrParseSanitizerArgs(Args);
|
||||
if (!SanitizerArguments.get())
|
||||
SanitizerArguments.reset(new SanitizerArgs(*this, Args));
|
||||
return *SanitizerArguments.get();
|
||||
}
|
||||
|
||||
std::string ToolChain::getDefaultUniversalArchName() const {
|
||||
|
|
|
@ -300,10 +300,11 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
|
|||
}
|
||||
}
|
||||
|
||||
const SanitizerArgs &Sanitize = getDriver().getOrParseSanitizerArgs(Args);
|
||||
const SanitizerArgs &Sanitize = getSanitizerArgs();
|
||||
|
||||
// Add Ubsan runtime library, if required.
|
||||
if (Sanitize.needsUbsanRt()) {
|
||||
// FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds.
|
||||
if (isTargetIPhoneOS()) {
|
||||
getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
|
||||
<< "-fsanitize=undefined";
|
||||
|
@ -318,6 +319,7 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args,
|
|||
// Add ASAN runtime library, if required. Dynamic libraries and bundles
|
||||
// should not be linked with the runtime library.
|
||||
if (Sanitize.needsAsanRt()) {
|
||||
// FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds.
|
||||
if (isTargetIPhoneOS() && !isTargetIOSSimulator()) {
|
||||
getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
|
||||
<< "-fsanitize=address";
|
||||
|
@ -2722,7 +2724,7 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
|
|||
}
|
||||
|
||||
bool Linux::isPIEDefault() const {
|
||||
return getSanitizerArgs().hasZeroBaseShadow(*this);
|
||||
return getSanitizerArgs().hasZeroBaseShadow();
|
||||
}
|
||||
|
||||
/// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.
|
||||
|
|
|
@ -2942,8 +2942,8 @@ 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);
|
||||
|
||||
const SanitizerArgs &Sanitize = D.getOrParseSanitizerArgs(Args);
|
||||
Sanitize.addArgs(getToolChain(), Args, CmdArgs);
|
||||
const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs();
|
||||
Sanitize.addArgs(Args, CmdArgs);
|
||||
|
||||
if (!Args.hasFlag(options::OPT_fsanitize_recover,
|
||||
options::OPT_fno_sanitize_recover,
|
||||
|
@ -6188,10 +6188,10 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
const Driver &D = ToolChain.getDriver();
|
||||
const bool isAndroid =
|
||||
ToolChain.getTriple().getEnvironment() == llvm::Triple::Android;
|
||||
const SanitizerArgs &Sanitize = D.getOrParseSanitizerArgs(Args);
|
||||
const SanitizerArgs &Sanitize = ToolChain.getSanitizerArgs();
|
||||
const bool IsPIE =
|
||||
!Args.hasArg(options::OPT_shared) &&
|
||||
(Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow(ToolChain));
|
||||
(Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow());
|
||||
|
||||
ArgStringList CmdArgs;
|
||||
|
||||
|
@ -6722,7 +6722,7 @@ void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
ImplibName.str()));
|
||||
}
|
||||
|
||||
if (getToolChain().getDriver().getOrParseSanitizerArgs(Args).needsAsanRt()) {
|
||||
if (getToolChain().getSanitizerArgs().needsAsanRt()) {
|
||||
CmdArgs.push_back(Args.MakeArgString("-debug"));
|
||||
CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
|
||||
SmallString<128> LibSanitizer(getToolChain().getDriver().ResourceDir);
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED
|
||||
// CHECK-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift|unreachable|return|vla-bound|alignment|null|vptr|object-size|float-cast-overflow|array-bounds|enum|bool),?){16}"}}
|
||||
|
||||
// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-DARWIN
|
||||
// CHECK-UNDEFINED-DARWIN: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift|unreachable|return|vla-bound|alignment|null|vptr|object-size|float-cast-overflow|array-bounds|enum|bool),?){15}"}}
|
||||
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTEGER
|
||||
// CHECK-INTEGER: "-fsanitize={{((signed-integer-overflow|unsigned-integer-overflow|integer-divide-by-zero|shift),?){4}"}}
|
||||
|
||||
|
@ -96,12 +99,12 @@
|
|||
// OK
|
||||
|
||||
// RUN: %clang -target x86_64-linux-gnu -fcatch-undefined-behavior -fthread-sanitizer -fno-thread-sanitizer -faddress-sanitizer -fno-address-sanitizer -fbounds-checking -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-DEPRECATED
|
||||
// CHECK-DEPRECATED: argument '-fcatch-undefined-behavior' is deprecated, use '-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error' instead
|
||||
// CHECK-DEPRECATED: argument '-fthread-sanitizer' is deprecated, use '-fsanitize=thread' instead
|
||||
// CHECK-DEPRECATED: argument '-fno-thread-sanitizer' is deprecated, use '-fno-sanitize=thread' instead
|
||||
// CHECK-DEPRECATED: argument '-faddress-sanitizer' is deprecated, use '-fsanitize=address' instead
|
||||
// CHECK-DEPRECATED: argument '-fno-address-sanitizer' is deprecated, use '-fno-sanitize=address' instead
|
||||
// CHECK-DEPRECATED: argument '-fbounds-checking' is deprecated, use '-fsanitize=local-bounds' instead
|
||||
// CHECK-DEPRECATED: argument '-fno-address-sanitizer' is deprecated, use '-fno-sanitize=address' instead
|
||||
// CHECK-DEPRECATED: argument '-faddress-sanitizer' is deprecated, use '-fsanitize=address' instead
|
||||
// CHECK-DEPRECATED: argument '-fno-thread-sanitizer' is deprecated, use '-fno-sanitize=thread' instead
|
||||
// CHECK-DEPRECATED: argument '-fthread-sanitizer' is deprecated, use '-fsanitize=thread' instead
|
||||
// CHECK-DEPRECATED: argument '-fcatch-undefined-behavior' is deprecated, use '-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error' instead
|
||||
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-NO-PIE
|
||||
// CHECK-TSAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
|
||||
|
@ -152,3 +155,27 @@
|
|||
// 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='
|
||||
|
||||
// RUN: %clang -target i686-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-X86
|
||||
// CHECK-MSAN-X86: error: unsupported option '-fsanitize=memory' for target 'i686--linux-gnu'
|
||||
|
||||
// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-DARWIN
|
||||
// CHECK-MSAN-DARWIN: unsupported option '-fsanitize=memory' for target 'x86_64-apple-darwin10'
|
||||
|
||||
// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=memory -fno-sanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-NOMSAN-DARWIN
|
||||
// CHECK-MSAN-NOMSAN-DARWIN-NOT: unsupported option
|
||||
|
||||
// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=memory -fsanitize=thread,memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-TSAN-MSAN-DARWIN
|
||||
// CHECK-MSAN-TSAN-MSAN-DARWIN: unsupported option '-fsanitize=thread,memory' for target 'x86_64-apple-darwin10'
|
||||
// CHECK-MSAN-TSAN-MSAN-DARWIN-NOT: unsupported option
|
||||
|
||||
// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=thread,memory -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-MSAN-MSAN-DARWIN
|
||||
// CHECK-TSAN-MSAN-MSAN-DARWIN: unsupported option '-fsanitize=memory' for target 'x86_64-apple-darwin10'
|
||||
// CHECK-TSAN-MSAN-MSAN-DARWIN: unsupported option '-fsanitize=thread' for target 'x86_64-apple-darwin10'
|
||||
// CHECK-TSAN-MSAN-MSAN-DARWIN-NOT: unsupported option
|
||||
|
||||
// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-DARWIN
|
||||
// CHECK-FSAN-DARWIN: unsupported option '-fsanitize=function' for target 'x86_64-apple-darwin10'
|
||||
|
||||
// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=function -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-UBSAN-DARWIN
|
||||
// CHECK-FSAN-UBSAN-DARWIN: unsupported option '-fsanitize=function' for target 'x86_64-apple-darwin10'
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// RUN: %clang -target i386-unknown-unknown -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang -O1 -target i386-unknown-unknown -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang -O2 -target i386-unknown-unknown -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang -O3 -target i386-unknown-unknown -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang -target i386-unknown-unknown -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang -O1 -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang -O2 -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang -O3 -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
|
||||
// Verify that -fsanitize=thread invokes tsan instrumentation.
|
||||
|
||||
int foo(int *a) { return *a; }
|
||||
|
|
Loading…
Reference in New Issue