summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.cpp141
1 files changed, 81 insertions, 60 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.cpp b/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.cpp
index f4f6dad..7a442c8 100644
--- a/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
#include "clang/Driver/SanitizerArgs.h"
-#include "Tools.h"
+#include "ToolChains/CommonArgs.h"
#include "clang/Basic/Sanitizers.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
@@ -26,18 +26,19 @@ using namespace clang::driver;
using namespace llvm::opt;
enum : SanitizerMask {
- NeedsUbsanRt = Undefined | Integer | CFI,
+ NeedsUbsanRt = Undefined | Integer | Nullability | CFI,
NeedsUbsanCxxRt = Vptr | CFI,
NotAllowedWithTrap = Vptr,
RequiresPIE = DataFlow,
NeedsUnwindTables = Address | Thread | Memory | DataFlow,
- SupportsCoverage = Address | Memory | Leak | Undefined | Integer | DataFlow,
- RecoverableByDefault = Undefined | Integer,
+ SupportsCoverage = Address | KernelAddress | Memory | Leak | Undefined |
+ Integer | Nullability | DataFlow | Fuzzer,
+ RecoverableByDefault = Undefined | Integer | Nullability,
Unrecoverable = Unreachable | Return,
LegacyFsanitizeRecoverMask = Undefined | Integer,
NeedsLTO = CFI,
- TrappingSupported =
- (Undefined & ~Vptr) | UnsignedIntegerOverflow | LocalBounds | CFI,
+ TrappingSupported = (Undefined & ~Vptr) | UnsignedIntegerOverflow |
+ Nullability | LocalBounds | CFI,
TrappingDefault = CFI,
CFIClasses = CFIVCall | CFINVCall | CFIDerivedCast | CFIUnrelatedCast,
};
@@ -47,13 +48,15 @@ enum CoverageFeature {
CoverageBB = 1 << 1,
CoverageEdge = 1 << 2,
CoverageIndirCall = 1 << 3,
- CoverageTraceBB = 1 << 4,
+ CoverageTraceBB = 1 << 4, // Deprecated.
CoverageTraceCmp = 1 << 5,
CoverageTraceDiv = 1 << 6,
CoverageTraceGep = 1 << 7,
- Coverage8bitCounters = 1 << 8,
+ Coverage8bitCounters = 1 << 8, // Deprecated.
CoverageTracePC = 1 << 9,
CoverageTracePCGuard = 1 << 10,
+ CoverageInline8bitCounters = 1 << 12,
+ CoverageNoPrune = 1 << 11,
};
/// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
@@ -205,12 +208,28 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
SanitizerMask TrappingKinds = parseSanitizeTrapArgs(D, Args);
SanitizerMask InvalidTrappingKinds = TrappingKinds & NotAllowedWithTrap;
+ // The object size sanitizer should not be enabled at -O0.
+ Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
+ bool RemoveObjectSizeAtO0 =
+ !OptLevel || OptLevel->getOption().matches(options::OPT_O0);
+
for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
I != E; ++I) {
const auto *Arg = *I;
if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
Arg->claim();
- SanitizerMask Add = parseArgValues(D, Arg, true);
+ SanitizerMask Add = parseArgValues(D, Arg, /*AllowGroups=*/true);
+
+ if (RemoveObjectSizeAtO0) {
+ AllRemove |= SanitizerKind::ObjectSize;
+
+ // The user explicitly enabled the object size sanitizer. Warn that
+ // that this does nothing at -O0.
+ if (Add & SanitizerKind::ObjectSize)
+ D.Diag(diag::warn_drv_object_size_disabled_O0)
+ << Arg->getAsString(Args);
+ }
+
AllAddedKinds |= expandSanitizerGroups(Add);
// Avoid diagnosing any sanitizer which is disabled later.
@@ -264,6 +283,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
Add &= ~InvalidTrappingKinds;
Add &= Supported;
+ // Enable coverage if the fuzzing flag is set.
+ if (Add & Fuzzer)
+ CoverageFeatures |= CoverageTracePCGuard | CoverageIndirCall | CoverageTraceCmp;
+
Kinds |= Add;
} else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
Arg->claim();
@@ -468,34 +491,12 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
int LegacySanitizeCoverage;
if (Arg->getNumValues() == 1 &&
!StringRef(Arg->getValue(0))
- .getAsInteger(0, LegacySanitizeCoverage) &&
- LegacySanitizeCoverage >= 0 && LegacySanitizeCoverage <= 4) {
- switch (LegacySanitizeCoverage) {
- case 0:
- CoverageFeatures = 0;
- Arg->claim();
- break;
- case 1:
- D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
- << "-fsanitize-coverage=func";
- CoverageFeatures = CoverageFunc;
- break;
- case 2:
- D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
- << "-fsanitize-coverage=bb";
- CoverageFeatures = CoverageBB;
- break;
- case 3:
- D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
- << "-fsanitize-coverage=edge";
- CoverageFeatures = CoverageEdge;
- break;
- case 4:
+ .getAsInteger(0, LegacySanitizeCoverage)) {
+ CoverageFeatures = 0;
+ Arg->claim();
+ if (LegacySanitizeCoverage != 0) {
D.Diag(diag::warn_drv_deprecated_arg)
- << Arg->getAsString(Args)
- << "-fsanitize-coverage=edge,indirect-calls";
- CoverageFeatures = CoverageEdge | CoverageIndirCall;
- break;
+ << Arg->getAsString(Args) << "-fsanitize-coverage=trace-pc-guard";
}
continue;
}
@@ -528,20 +529,27 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
<< "-fsanitize-coverage=edge";
// Basic block tracing and 8-bit counters require some type of coverage
// enabled.
- int CoverageTypes = CoverageFunc | CoverageBB | CoverageEdge;
- if ((CoverageFeatures & CoverageTraceBB) &&
- !(CoverageFeatures & CoverageTypes))
- D.Diag(clang::diag::err_drv_argument_only_allowed_with)
+ if (CoverageFeatures & CoverageTraceBB)
+ D.Diag(clang::diag::warn_drv_deprecated_arg)
<< "-fsanitize-coverage=trace-bb"
- << "-fsanitize-coverage=(func|bb|edge)";
- if ((CoverageFeatures & Coverage8bitCounters) &&
- !(CoverageFeatures & CoverageTypes))
- D.Diag(clang::diag::err_drv_argument_only_allowed_with)
+ << "-fsanitize-coverage=trace-pc-guard";
+ if (CoverageFeatures & Coverage8bitCounters)
+ D.Diag(clang::diag::warn_drv_deprecated_arg)
<< "-fsanitize-coverage=8bit-counters"
- << "-fsanitize-coverage=(func|bb|edge)";
+ << "-fsanitize-coverage=trace-pc-guard";
+
+ int InsertionPointTypes = CoverageFunc | CoverageBB | CoverageEdge;
+ if ((CoverageFeatures & InsertionPointTypes) &&
+ !(CoverageFeatures &(CoverageTracePC | CoverageTracePCGuard))) {
+ D.Diag(clang::diag::warn_drv_deprecated_arg)
+ << "-fsanitize-coverage=[func|bb|edge]"
+ << "-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc]";
+ }
+
// trace-pc w/o func/bb/edge implies edge.
- if ((CoverageFeatures & (CoverageTracePC | CoverageTracePCGuard)) &&
- !(CoverageFeatures & CoverageTypes))
+ if ((CoverageFeatures &
+ (CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters)) &&
+ !(CoverageFeatures & InsertionPointTypes))
CoverageFeatures |= CoverageEdge;
if (AllAddedKinds & Address) {
@@ -573,12 +581,18 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
}
}
- if (Arg *A = Args.getLastArg(
- options::OPT_fsanitize_address_use_after_scope,
- options::OPT_fno_sanitize_address_use_after_scope)) {
- AsanUseAfterScope = A->getOption().getID() ==
- options::OPT_fsanitize_address_use_after_scope;
- }
+ AsanUseAfterScope = Args.hasFlag(
+ options::OPT_fsanitize_address_use_after_scope,
+ options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
+
+ // As a workaround for a bug in gold 2.26 and earlier, dead stripping of
+ // globals in ASan is disabled by default on ELF targets.
+ // See https://sourceware.org/bugzilla/show_bug.cgi?id=19002
+ AsanGlobalsDeadStripping =
+ !TC.getTriple().isOSBinFormatELF() ||
+ Args.hasArg(options::OPT_fsanitize_address_globals_dead_stripping);
+ } else {
+ AsanUseAfterScope = false;
}
// Parse -link-cxx-sanitizer flag.
@@ -640,10 +654,12 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"),
std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"),
- std::make_pair(CoverageTracePCGuard, "-fsanitize-coverage-trace-pc-guard")};
+ std::make_pair(CoverageTracePCGuard, "-fsanitize-coverage-trace-pc-guard"),
+ std::make_pair(CoverageInline8bitCounters, "-fsanitize-coverage-inline-8bit-counters"),
+ std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune")};
for (auto F : CoverageFlags) {
if (CoverageFeatures & F.first)
- CmdArgs.push_back(Args.MakeArgString(F.second));
+ CmdArgs.push_back(F.second);
}
if (TC.getTriple().isOSWindows() && needsUbsanRt()) {
@@ -696,7 +712,7 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
llvm::utostr(MsanTrackOrigins)));
if (MsanUseAfterDtor)
- CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-use-after-dtor"));
+ CmdArgs.push_back("-fsanitize-memory-use-after-dtor");
// FIXME: Pass these parameters as function attributes, not as -llvm flags.
if (!TsanMemoryAccess) {
@@ -715,17 +731,20 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
}
if (CfiCrossDso)
- CmdArgs.push_back(Args.MakeArgString("-fsanitize-cfi-cross-dso"));
+ CmdArgs.push_back("-fsanitize-cfi-cross-dso");
if (Stats)
- CmdArgs.push_back(Args.MakeArgString("-fsanitize-stats"));
+ CmdArgs.push_back("-fsanitize-stats");
if (AsanFieldPadding)
CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
llvm::utostr(AsanFieldPadding)));
if (AsanUseAfterScope)
- CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-use-after-scope"));
+ CmdArgs.push_back("-fsanitize-address-use-after-scope");
+
+ if (AsanGlobalsDeadStripping)
+ CmdArgs.push_back("-fsanitize-address-globals-dead-stripping");
// MSan: Workaround for PR16386.
// ASan: This is mainly to help LSan with cases such as
@@ -733,7 +752,7 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
// We can't make this conditional on -fsanitize=leak, as that flag shouldn't
// affect compilation.
if (Sanitizers.has(Memory) || Sanitizers.has(Address))
- CmdArgs.push_back(Args.MakeArgString("-fno-assume-sane-operator-new"));
+ CmdArgs.push_back("-fno-assume-sane-operator-new");
// Require -fvisibility= flag on non-Windows when compiling if vptr CFI is
// enabled.
@@ -797,6 +816,8 @@ int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A) {
.Case("8bit-counters", Coverage8bitCounters)
.Case("trace-pc", CoverageTracePC)
.Case("trace-pc-guard", CoverageTracePCGuard)
+ .Case("no-prune", CoverageNoPrune)
+ .Case("inline-8bit-counters", CoverageInline8bitCounters)
.Default(0);
if (F == 0)
D.Diag(clang::diag::err_drv_unsupported_option_argument)
OpenPOWER on IntegriCloud