forked from OSchip/llvm-project
Move sanitizer parser and group expander from Driver to Basic.
No functional change. Differential Revision: http://reviews.llvm.org/D9621 llvm-svn: 237056
This commit is contained in:
parent
3eea677f3a
commit
bf59c34bfd
|
@ -15,6 +15,9 @@
|
|||
#ifndef LLVM_CLANG_BASIC_SANITIZERS_H
|
||||
#define LLVM_CLANG_BASIC_SANITIZERS_H
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace clang {
|
||||
|
@ -62,6 +65,14 @@ struct SanitizerSet {
|
|||
SanitizerMask Mask;
|
||||
};
|
||||
|
||||
/// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
|
||||
/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
|
||||
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
|
||||
|
||||
/// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
|
||||
/// this group enables.
|
||||
SanitizerMask expandSanitizerGroups(SanitizerMask Kinds);
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "clang/Basic/Sanitizers.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
|
||||
using namespace clang;
|
||||
|
@ -34,3 +37,22 @@ void SanitizerSet::clear() {
|
|||
bool SanitizerSet::empty() const {
|
||||
return Mask == 0;
|
||||
}
|
||||
|
||||
SanitizerMask clang::parseSanitizerValue(StringRef Value, bool AllowGroups) {
|
||||
SanitizerMask ParsedKind = llvm::StringSwitch<SanitizerMask>(Value)
|
||||
#define SANITIZER(NAME, ID) .Case(NAME, SanitizerKind::ID)
|
||||
#define SANITIZER_GROUP(NAME, ID, ALIAS) \
|
||||
.Case(NAME, AllowGroups ? SanitizerKind::ID##Group : 0)
|
||||
#include "clang/Basic/Sanitizers.def"
|
||||
.Default(0);
|
||||
return ParsedKind;
|
||||
}
|
||||
|
||||
SanitizerMask clang::expandSanitizerGroups(SanitizerMask Kinds) {
|
||||
#define SANITIZER(NAME, ID)
|
||||
#define SANITIZER_GROUP(NAME, ID, ALIAS) \
|
||||
if (Kinds & SanitizerKind::ID##Group) \
|
||||
Kinds |= SanitizerKind::ID;
|
||||
#include "clang/Basic/Sanitizers.def"
|
||||
return Kinds;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "clang/Driver/SanitizerArgs.h"
|
||||
#include "clang/Basic/Sanitizers.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Driver/DriverDiagnostic.h"
|
||||
#include "clang/Driver/Options.h"
|
||||
|
@ -45,10 +46,6 @@ enum CoverageFeature {
|
|||
Coverage8bitCounters = 1 << 6,
|
||||
};
|
||||
|
||||
/// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
|
||||
/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
|
||||
static SanitizerMask parseValue(const char *Value);
|
||||
|
||||
/// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
|
||||
/// invalid components. Returns a SanitizerMask.
|
||||
static SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
|
||||
|
@ -77,10 +74,6 @@ static std::string describeSanitizeArg(const llvm::opt::Arg *A,
|
|||
/// Sanitizers set.
|
||||
static std::string toString(const clang::SanitizerSet &Sanitizers);
|
||||
|
||||
/// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
|
||||
/// this group enables.
|
||||
static SanitizerMask expandGroups(SanitizerMask Kinds);
|
||||
|
||||
static SanitizerMask getToolchainUnsupportedKinds(const ToolChain &TC) {
|
||||
bool IsFreeBSD = TC.getTriple().getOS() == llvm::Triple::FreeBSD;
|
||||
bool IsLinux = TC.getTriple().getOS() == llvm::Triple::Linux;
|
||||
|
@ -212,7 +205,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
|
|||
AllRemove |= Vptr;
|
||||
}
|
||||
|
||||
Add = expandGroups(Add);
|
||||
Add = expandSanitizerGroups(Add);
|
||||
// Group expansion may have enabled a sanitizer which is disabled later.
|
||||
Add &= ~AllRemove;
|
||||
// Silently discard any unsupported sanitizers implicitly enabled through
|
||||
|
@ -223,7 +216,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
|
|||
} else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
|
||||
Arg->claim();
|
||||
SanitizerMask Remove = parseArgValues(D, Arg, true);
|
||||
AllRemove |= expandGroups(Remove);
|
||||
AllRemove |= expandSanitizerGroups(Remove);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,11 +267,11 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
|
|||
const char *DeprecatedReplacement = nullptr;
|
||||
if (Arg->getOption().matches(options::OPT_fsanitize_recover)) {
|
||||
DeprecatedReplacement = "-fsanitize-recover=undefined,integer";
|
||||
RecoverableKinds |= expandGroups(LegacyFsanitizeRecoverMask);
|
||||
RecoverableKinds |= expandSanitizerGroups(LegacyFsanitizeRecoverMask);
|
||||
Arg->claim();
|
||||
} else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover)) {
|
||||
DeprecatedReplacement = "-fno-sanitize-recover=undefined,integer";
|
||||
RecoverableKinds &= ~expandGroups(LegacyFsanitizeRecoverMask);
|
||||
RecoverableKinds &= ~expandSanitizerGroups(LegacyFsanitizeRecoverMask);
|
||||
Arg->claim();
|
||||
} else if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) {
|
||||
SanitizerMask Add = parseArgValues(D, Arg, true);
|
||||
|
@ -292,10 +285,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
|
|||
<< Arg->getOption().getName() << toString(SetToDiagnose);
|
||||
DiagnosedUnrecoverableKinds |= KindsToDiagnose;
|
||||
}
|
||||
RecoverableKinds |= expandGroups(Add);
|
||||
RecoverableKinds |= expandSanitizerGroups(Add);
|
||||
Arg->claim();
|
||||
} else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover_EQ)) {
|
||||
RecoverableKinds &= ~expandGroups(parseArgValues(D, Arg, true));
|
||||
RecoverableKinds &= ~expandSanitizerGroups(parseArgValues(D, Arg, true));
|
||||
Arg->claim();
|
||||
}
|
||||
if (DeprecatedReplacement) {
|
||||
|
@ -524,22 +517,6 @@ void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args,
|
|||
CmdArgs.push_back(Args.MakeArgString("-fno-assume-sane-operator-new"));
|
||||
}
|
||||
|
||||
SanitizerMask parseValue(const char *Value) {
|
||||
SanitizerMask ParsedKind = llvm::StringSwitch<SanitizerMask>(Value)
|
||||
#define SANITIZER(NAME, ID) .Case(NAME, ID)
|
||||
#define SANITIZER_GROUP(NAME, ID, ALIAS) .Case(NAME, ID##Group)
|
||||
#include "clang/Basic/Sanitizers.def"
|
||||
.Default(0);
|
||||
return ParsedKind;
|
||||
}
|
||||
|
||||
SanitizerMask expandGroups(SanitizerMask Kinds) {
|
||||
#define SANITIZER(NAME, ID)
|
||||
#define SANITIZER_GROUP(NAME, ID, ALIAS) if (Kinds & ID##Group) Kinds |= ID;
|
||||
#include "clang/Basic/Sanitizers.def"
|
||||
return Kinds;
|
||||
}
|
||||
|
||||
SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
|
||||
bool DiagnoseErrors) {
|
||||
assert((A->getOption().matches(options::OPT_fsanitize_EQ) ||
|
||||
|
@ -556,7 +533,7 @@ SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
|
|||
0 == strcmp("all", Value))
|
||||
Kind = 0;
|
||||
else
|
||||
Kind = parseValue(Value);
|
||||
Kind = parseSanitizerValue(Value, /*AllowGroups=*/true);
|
||||
|
||||
if (Kind)
|
||||
Kinds |= Kind;
|
||||
|
@ -597,11 +574,13 @@ std::string lastArgumentForMask(const Driver &D, const llvm::opt::ArgList &Args,
|
|||
I != E; ++I) {
|
||||
const auto *Arg = *I;
|
||||
if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
|
||||
SanitizerMask AddKinds = expandGroups(parseArgValues(D, Arg, false));
|
||||
SanitizerMask AddKinds =
|
||||
expandSanitizerGroups(parseArgValues(D, Arg, false));
|
||||
if (AddKinds & Mask)
|
||||
return describeSanitizeArg(Arg, Mask);
|
||||
} else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
|
||||
SanitizerMask RemoveKinds = expandGroups(parseArgValues(D, Arg, false));
|
||||
SanitizerMask RemoveKinds =
|
||||
expandSanitizerGroups(parseArgValues(D, Arg, false));
|
||||
Mask &= ~RemoveKinds;
|
||||
}
|
||||
}
|
||||
|
@ -614,7 +593,9 @@ std::string describeSanitizeArg(const llvm::opt::Arg *A, SanitizerMask Mask) {
|
|||
|
||||
std::string Sanitizers;
|
||||
for (int i = 0, n = A->getNumValues(); i != n; ++i) {
|
||||
if (expandGroups(parseValue(A->getValue(i))) & Mask) {
|
||||
if (expandSanitizerGroups(
|
||||
parseSanitizerValue(A->getValue(i), /*AllowGroups=*/true)) &
|
||||
Mask) {
|
||||
if (!Sanitizers.empty())
|
||||
Sanitizers += ",";
|
||||
Sanitizers += A->getValue(i);
|
||||
|
|
|
@ -329,10 +329,7 @@ static void parseSanitizerKinds(StringRef FlagName,
|
|||
const std::vector<std::string> &Sanitizers,
|
||||
DiagnosticsEngine &Diags, SanitizerSet &S) {
|
||||
for (const auto &Sanitizer : Sanitizers) {
|
||||
SanitizerMask K = llvm::StringSwitch<SanitizerMask>(Sanitizer)
|
||||
#define SANITIZER(NAME, ID) .Case(NAME, SanitizerKind::ID)
|
||||
#include "clang/Basic/Sanitizers.def"
|
||||
.Default(0);
|
||||
SanitizerMask K = parseSanitizerValue(Sanitizer, /*AllowGroups=*/false);
|
||||
if (K == 0)
|
||||
Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue