diff options
author | Alexey Samsonov <vonosmas@gmail.com> | 2015-01-12 22:39:12 +0000 |
---|---|---|
committer | Alexey Samsonov <vonosmas@gmail.com> | 2015-01-12 22:39:12 +0000 |
commit | 8845952b54a7574cedbbd0661e889cd4e2d5947b (patch) | |
tree | cac9ea08214180cb195bc54409842254053fa5f4 /clang/lib/Frontend/CompilerInvocation.cpp | |
parent | d88ab87064d9b366393d58066f3bee8111f6cec4 (diff) | |
download | llvm-8845952b54a7574cedbbd0661e889cd4e2d5947b.zip llvm-8845952b54a7574cedbbd0661e889cd4e2d5947b.tar.gz llvm-8845952b54a7574cedbbd0661e889cd4e2d5947b.tar.bz2 |
Reimplement -fsanitize-recover family of flags.
Introduce the following -fsanitize-recover flags:
- -fsanitize-recover=<list>: Enable recovery for selected checks or
group of checks. It is forbidden to explicitly list unrecoverable
sanitizers here (that is, "address", "unreachable", "return").
- -fno-sanitize-recover=<list>: Disable recovery for selected checks or
group of checks.
- -f(no-)?sanitize-recover is now a synonym for
-f(no-)?sanitize-recover=undefined,integer and will soon be deprecated.
These flags are parsed left to right, and mask of "recoverable"
sanitizer is updated accordingly, much like what we do for -fsanitize= flags.
-fsanitize= and -fsanitize-recover= flag families are independent.
CodeGen change: If there is a single UBSan handler function, responsible
for implementing multiple checks, which have different recoverable setting,
then we emit two handler calls instead of one:
the first one for the set of "unrecoverable" checks, another one - for
set of "recoverable" checks. If all checks implemented by a handler have the
same recoverability setting, then the generated code will be the same.
llvm-svn: 225719
Diffstat (limited to 'clang/lib/Frontend/CompilerInvocation.cpp')
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index d630b5b..0f6f01d 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -325,6 +325,21 @@ GenerateOptimizationRemarkRegex(DiagnosticsEngine &Diags, ArgList &Args, return Pattern; } +static void parseSanitizerKinds(StringRef FlagName, + const std::vector<std::string> &Sanitizers, + DiagnosticsEngine &Diags, SanitizerSet &S) { + for (const auto &Sanitizer : Sanitizers) { + SanitizerKind K = llvm::StringSwitch<SanitizerKind>(Sanitizer) +#define SANITIZER(NAME, ID) .Case(NAME, SanitizerKind::ID) +#include "clang/Basic/Sanitizers.def" + .Default(SanitizerKind::Unknown); + if (K == SanitizerKind::Unknown) + Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer; + else + S.set(K, true); + } +} + static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, DiagnosticsEngine &Diags, const TargetOptions &TargetOpts) { @@ -465,7 +480,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.MainFileName = Args.getLastArgValue(OPT_main_file_name); Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier); - Opts.SanitizeRecover = !Args.hasArg(OPT_fno_sanitize_recover); Opts.DisableGCov = Args.hasArg(OPT_test_coverage); Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data); @@ -596,6 +610,12 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.RewriteMapFiles = Args.getAllArgValues(OPT_frewrite_map_file); + // Parse -fsanitize-recover= arguments. + // FIXME: Report unrecoverable sanitizers incorrectly specified here. + parseSanitizerKinds("-fsanitize-recover=", + Args.getAllArgValues(OPT_fsanitize_recover_EQ), Diags, + Opts.SanitizeRecover); + return Success; } @@ -1635,18 +1655,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, } // Parse -fsanitize= arguments. - std::vector<std::string> Sanitizers = Args.getAllArgValues(OPT_fsanitize_EQ); - for (const auto &Sanitizer : Sanitizers) { - SanitizerKind K = llvm::StringSwitch<SanitizerKind>(Sanitizer) -#define SANITIZER(NAME, ID) .Case(NAME, SanitizerKind::ID) -#include "clang/Basic/Sanitizers.def" - .Default(SanitizerKind::Unknown); - if (K == SanitizerKind::Unknown) - Diags.Report(diag::err_drv_invalid_value) - << "-fsanitize=" << Sanitizer; - else - Opts.Sanitize.set(K, true); - } + parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ), + Diags, Opts.Sanitize); // -fsanitize-address-field-padding=N has to be a LangOpt, parse it here. Opts.SanitizeAddressFieldPadding = getLastArgIntValue(Args, OPT_fsanitize_address_field_padding, 0, Diags); |