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
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user