r222105 - [Sanitizer] Parse and produce all sanitizer-relevant arguments in SanitizerArgs.
Alexey Samsonov
vonosmas at gmail.com
Sun Nov 16 12:53:53 PST 2014
Author: samsonov
Date: Sun Nov 16 14:53:53 2014
New Revision: 222105
URL: http://llvm.org/viewvc/llvm-project?rev=222105&view=rev
Log:
[Sanitizer] Parse and produce all sanitizer-relevant arguments in SanitizerArgs.
In particular, make SanitizerArgs responsible for parsing
and passing down to frontend -fsanitize-recover and
-fsanitize-undefined-trap-on-error flags.
Simplify parsing -f(no-)sanitize= flags parsing: get rid of
too complex filterUnsupportedKinds function.
No functionality change.
Modified:
cfe/trunk/include/clang/Driver/SanitizerArgs.h
cfe/trunk/lib/Driver/SanitizerArgs.cpp
cfe/trunk/lib/Driver/Tools.cpp
cfe/trunk/test/Driver/fsanitize.c
Modified: cfe/trunk/include/clang/Driver/SanitizerArgs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/SanitizerArgs.h?rev=222105&r1=222104&r2=222105&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/SanitizerArgs.h (original)
+++ cfe/trunk/include/clang/Driver/SanitizerArgs.h Sun Nov 16 14:53:53 2014
@@ -22,6 +22,8 @@ class ToolChain;
class SanitizerArgs {
SanitizerSet Sanitizers;
+ bool SanitizeRecover;
+
std::string BlacklistFile;
int SanitizeCoverage;
int MsanTrackOrigins;
Modified: cfe/trunk/lib/Driver/SanitizerArgs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/SanitizerArgs.cpp?rev=222105&r1=222104&r2=222105&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/SanitizerArgs.cpp (original)
+++ cfe/trunk/lib/Driver/SanitizerArgs.cpp Sun Nov 16 14:53:53 2014
@@ -109,17 +109,32 @@ static std::string lastArgumentForKind(c
/// "-fsanitize=alignment".
static std::string describeSanitizeArg(const llvm::opt::Arg *A, unsigned Mask);
+/// Produce a string containing comma-separated names of sanitizers in \p
+/// Sanitizers set.
+static std::string toString(const clang::SanitizerSet &Sanitizers);
+
/// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
/// this group enables.
static unsigned expandGroups(unsigned Kinds);
-/// Return the subset of \p Kinds supported by toolchain \p TC. If
-/// \p DiagnoseErrors is true, produce an error diagnostic for each sanitizer
-/// removed from \p Kinds.
-static unsigned filterUnsupportedKinds(const ToolChain &TC, unsigned Kinds,
- const llvm::opt::Arg *A,
- bool DiagnoseErrors,
- unsigned &DiagnosedKinds);
+static unsigned getToolchainUnsupportedKinds(const ToolChain &TC) {
+ bool IsFreeBSD = TC.getTriple().getOS() == llvm::Triple::FreeBSD;
+ bool IsLinux = TC.getTriple().getOS() == llvm::Triple::Linux;
+ bool IsX86 = TC.getTriple().getArch() == llvm::Triple::x86;
+ bool IsX86_64 = TC.getTriple().getArch() == llvm::Triple::x86_64;
+
+ unsigned Unsupported = 0;
+ if (!(IsLinux && IsX86_64)) {
+ Unsupported |= Memory | DataFlow;
+ }
+ if (!((IsLinux || IsFreeBSD) && IsX86_64)) {
+ Unsupported |= Thread;
+ }
+ if (!(IsLinux && (IsX86 || IsX86_64))) {
+ Unsupported |= Function;
+ }
+ return Unsupported;
+}
bool SanitizerArgs::needsUbsanRt() const {
return !UbsanTrapOnError && hasOneOf(Sanitizers, NeedsUbsanRt);
@@ -135,6 +150,7 @@ bool SanitizerArgs::needsUnwindTables()
void SanitizerArgs::clear() {
Sanitizers.clear();
+ SanitizeRecover = false;
BlacklistFile = "";
SanitizeCoverage = 0;
MsanTrackOrigins = 0;
@@ -153,6 +169,8 @@ SanitizerArgs::SanitizerArgs(const ToolC
// argument or any argument after it.
unsigned DiagnosedKinds = 0; // All Kinds we have diagnosed up to now.
// Used to deduplicate diagnostics.
+ unsigned Kinds = 0;
+ unsigned NotSupported = getToolchainUnsupportedKinds(TC);
const Driver &D = TC.getDriver();
for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
I != E; ++I) {
@@ -165,20 +183,31 @@ SanitizerArgs::SanitizerArgs(const ToolC
// Avoid diagnosing any sanitizer which is disabled later.
Add &= ~AllRemove;
+
// At this point we have not expanded groups, so any unsupported sanitizers
// in Add are those which have been explicitly enabled. Diagnose them.
- Add = filterUnsupportedKinds(TC, Add, *I, /*DiagnoseErrors=*/true,
- DiagnosedKinds);
+ if (unsigned KindsToDiagnose = Add & NotSupported & ~DiagnosedKinds) {
+ // Only diagnose the new kinds.
+ std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
+ D.Diag(diag::err_drv_unsupported_opt_for_target) << Desc
+ << TC.getTriple().str();
+ DiagnosedKinds |= KindsToDiagnose;
+ }
+ Add &= ~NotSupported;
+
Add = expandGroups(Add);
// Group expansion may have enabled a sanitizer which is disabled later.
Add &= ~AllRemove;
// Silently discard any unsupported sanitizers implicitly enabled through
// group expansion.
- Add = filterUnsupportedKinds(TC, Add, *I, /*DiagnoseErrors=*/false,
- DiagnosedKinds);
+ Add &= ~NotSupported;
- addAllOf(Sanitizers, Add);
+ Kinds |= Add;
}
+ addAllOf(Sanitizers, Kinds);
+
+ SanitizeRecover = Args.hasFlag(options::OPT_fsanitize_recover,
+ options::OPT_fno_sanitize_recover, true);
UbsanTrapOnError =
Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error,
@@ -316,17 +345,30 @@ SanitizerArgs::SanitizerArgs(const ToolC
Args.hasArg(options::OPT_fsanitize_link_cxx_runtime) || D.CCCIsCXX();
}
+static std::string toString(const clang::SanitizerSet &Sanitizers) {
+ std::string Res;
+#define SANITIZER(NAME, ID) \
+ if (Sanitizers.has(clang::SanitizerKind::ID)) { \
+ if (!Res.empty()) \
+ Res += ","; \
+ Res += NAME; \
+ }
+#include "clang/Basic/Sanitizers.def"
+ return Res;
+}
+
void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const {
if (Sanitizers.empty())
return;
- SmallString<256> SanitizeOpt("-fsanitize=");
-#define SANITIZER(NAME, ID) \
- if (Sanitizers.has(SanitizerKind::ID)) \
- SanitizeOpt += NAME ",";
-#include "clang/Basic/Sanitizers.def"
- SanitizeOpt.pop_back();
- CmdArgs.push_back(Args.MakeArgString(SanitizeOpt));
+ CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers)));
+
+ if (!SanitizeRecover)
+ CmdArgs.push_back("-fno-sanitize-recover");
+
+ if (UbsanTrapOnError)
+ CmdArgs.push_back("-fsanitize-undefined-trap-on-error");
+
if (!BlacklistFile.empty()) {
SmallString<64> BlacklistOpt("-fsanitize-blacklist=");
BlacklistOpt += BlacklistFile;
@@ -383,39 +425,6 @@ unsigned expandGroups(unsigned Kinds) {
return Kinds;
}
-unsigned filterUnsupportedKinds(const ToolChain &TC, unsigned Kinds,
- const llvm::opt::Arg *A, bool DiagnoseErrors,
- unsigned &DiagnosedKinds) {
- bool IsFreeBSD = TC.getTriple().getOS() == llvm::Triple::FreeBSD;
- bool IsLinux = TC.getTriple().getOS() == llvm::Triple::Linux;
- bool IsX86 = TC.getTriple().getArch() == llvm::Triple::x86;
- bool IsX86_64 = TC.getTriple().getArch() == llvm::Triple::x86_64;
-
- unsigned KindsToFilterOut = 0;
- if (!(IsLinux && IsX86_64)) {
- KindsToFilterOut |= Memory | DataFlow;
- }
- if (!((IsLinux || IsFreeBSD) && IsX86_64)) {
- KindsToFilterOut |= Thread;
- }
- if (!(IsLinux && (IsX86 || IsX86_64))) {
- KindsToFilterOut |= Function;
- }
- KindsToFilterOut &= Kinds;
-
- // Do we have new kinds to diagnose?
- unsigned KindsToDiagnose = KindsToFilterOut & ~DiagnosedKinds;
- if (DiagnoseErrors && KindsToDiagnose) {
- // Only diagnose the new kinds.
- std::string Desc = describeSanitizeArg(A, KindsToDiagnose);
- TC.getDriver().Diag(clang::diag::err_drv_unsupported_opt_for_target)
- << Desc << TC.getTriple().str();
- DiagnosedKinds |= KindsToFilterOut;
- }
-
- return Kinds & ~KindsToFilterOut;
-}
-
unsigned parseArgValues(const Driver &D, const llvm::opt::Arg *A,
bool DiagnoseErrors) {
unsigned Kind = 0;
Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=222105&r1=222104&r2=222105&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Sun Nov 16 14:53:53 2014
@@ -3625,15 +3625,6 @@ void Clang::ConstructJob(Compilation &C,
const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs();
Sanitize.addArgs(Args, CmdArgs);
- if (!Args.hasFlag(options::OPT_fsanitize_recover,
- options::OPT_fno_sanitize_recover,
- true))
- CmdArgs.push_back("-fno-sanitize-recover");
-
- if (Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error,
- options::OPT_fno_sanitize_undefined_trap_on_error, false))
- CmdArgs.push_back("-fsanitize-undefined-trap-on-error");
-
// Report an error for -faltivec on anything other than PowerPC.
if (const Arg *A = Args.getLastArg(options::OPT_faltivec))
if (!(getToolChain().getArch() == llvm::Triple::ppc ||
Modified: cfe/trunk/test/Driver/fsanitize.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/fsanitize.c?rev=222105&r1=222104&r2=222105&view=diff
==============================================================================
--- cfe/trunk/test/Driver/fsanitize.c (original)
+++ cfe/trunk/test/Driver/fsanitize.c Sun Nov 16 14:53:53 2014
@@ -119,11 +119,11 @@
// RUN: %clang -target arm-linux-androideabi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-NO-ASAN
// CHECK-ANDROID-NO-ASAN: "-mrelocation-model" "pic"
-// RUN: %clang -target x86_64-linux-gnu %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER
-// RUN: %clang -target x86_64-linux-gnu %s -fsanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER
-// RUN: %clang -target x86_64-linux-gnu %s -fno-sanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER
-// RUN: %clang -target x86_64-linux-gnu %s -fno-sanitize-recover -fsanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER
-// RUN: %clang -target x86_64-linux-gnu %s -fsanitize-recover -fno-sanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER
+// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER
+// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fsanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER
+// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fno-sanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER
+// RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fno-sanitize-recover -fsanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER
+// RUZ: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fsanitize-recover -fno-sanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER
// CHECK-RECOVER-NOT: sanitize-recover
// CHECK-NO-RECOVER: "-fno-sanitize-recover"
More information about the cfe-commits
mailing list