diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.cpp | 141 |
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) |