Add -fsanitize=<sanitizers> argument to driver and frontend, and add

-fno-sanitize=<sanitizers> argument to driver. These allow ASan, TSan, and the
various UBSan checks to be enabled and disabled separately. Right now, the
different modes can't be combined, but the intention is that combining UBSan
and the other sanitizers will be permitted in the near future.

Currently, the UBSan checks will all be enabled if any of them is; that will be
fixed by the next patch.

llvm-svn: 167411
This commit is contained in:
Richard Smith
2012-11-05 22:04:41 +00:00
parent 18d2762048
commit 52be619c84
10 changed files with 308 additions and 23 deletions

View File

@@ -1273,6 +1273,37 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
case 1: Opts.setStackProtector(LangOptions::SSPOn); break;
case 2: Opts.setStackProtector(LangOptions::SSPReq); break;
}
// Parse -fsanitize= arguments.
std::vector<std::string> Sanitizers = Args.getAllArgValues(OPT_fsanitize_EQ);
for (unsigned I = 0, N = Sanitizers.size(); I != N; ++I) {
// Since the Opts.Sanitize* values are bitfields, it's a little tricky to
// efficiently map string values to them. Perform the mapping indirectly:
// convert strings to enumerated values, then switch over the enum to set
// the right bitfield value.
enum Sanitizer {
#define SANITIZER(NAME, ID) \
ID,
#include "clang/Basic/Sanitizers.def"
Unknown
};
switch (llvm::StringSwitch<unsigned>(Sanitizers[I])
#define SANITIZER(NAME, ID) \
.Case(NAME, ID)
#include "clang/Basic/Sanitizers.def"
.Default(Unknown)) {
#define SANITIZER(NAME, ID) \
case ID: \
Opts.Sanitize##ID = true; \
break;
#include "clang/Basic/Sanitizers.def"
case Unknown:
Diags.Report(diag::err_drv_invalid_value)
<< "-fsanitize=" << Sanitizers[I];
break;
}
}
}
static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,