DataFlowSanitizer; Clang changes.
DataFlowSanitizer is a generalised dynamic data flow analysis.
Unlike other Sanitizer tools, this tool is not designed to detect a
specific class of bugs on its own. Instead, it provides a generic
dynamic data flow analysis framework to be used by clients to help
detect application-specific issues within their own code.
Differential Revision: http://llvm-reviews.chandlerc.com/D966
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@187925 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index 79cbc38..1edd065 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -206,6 +206,11 @@
PM.add(createThreadSanitizerPass(CGOpts.SanitizerBlacklistFile));
}
+static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,
+ PassManagerBase &PM) {
+ PM.add(createDataFlowSanitizerPass());
+}
+
void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) {
unsigned OptLevel = CodeGenOpts.OptimizationLevel;
CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining();
@@ -265,6 +270,13 @@
addThreadSanitizerPass);
}
+ if (LangOpts.Sanitize.DataFlow) {
+ PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
+ addDataFlowSanitizerPass);
+ PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
+ addDataFlowSanitizerPass);
+ }
+
// Figure out TargetLibraryInfo.
Triple TargetTriple(TheModule->getTargetTriple());
PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple);
diff --git a/lib/Driver/SanitizerArgs.h b/lib/Driver/SanitizerArgs.h
index da6f4f6..58dece9 100644
--- a/lib/Driver/SanitizerArgs.h
+++ b/lib/Driver/SanitizerArgs.h
@@ -37,10 +37,11 @@
NeedsAsanRt = Address,
NeedsTsanRt = Thread,
NeedsMsanRt = Memory,
+ NeedsDfsanRt = DataFlow,
NeedsLeakDetection = Leak,
NeedsUbsanRt = Undefined | Integer,
NotAllowedWithTrap = Vptr,
- HasZeroBaseShadow = Thread | Memory
+ HasZeroBaseShadow = Thread | Memory | DataFlow
};
unsigned Kind;
std::string BlacklistFile;
@@ -66,6 +67,7 @@
return false;
return Kind & NeedsUbsanRt;
}
+ bool needsDfsanRt() const { return Kind & NeedsDfsanRt; }
bool sanitizesVptr() const { return Kind & Vptr; }
bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; }
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 254bf8b..4a3ce42 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -1860,6 +1860,12 @@
addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan_cxx", false);
}
+static void addDfsanRTLinux(const ToolChain &TC, const ArgList &Args,
+ ArgStringList &CmdArgs) {
+ if (!Args.hasArg(options::OPT_shared))
+ addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "dfsan", true);
+}
+
static bool shouldUseFramePointer(const ArgList &Args,
const llvm::Triple &Triple) {
if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer,
@@ -6275,6 +6281,8 @@
addMsanRTLinux(getToolChain(), Args, CmdArgs);
if (Sanitize.needsLsanRt())
addLsanRTLinux(getToolChain(), Args, CmdArgs);
+ if (Sanitize.needsDfsanRt())
+ addDfsanRTLinux(getToolChain(), Args, CmdArgs);
// The profile runtime also needs access to system libraries.
addProfileRTLinux(getToolChain(), Args, CmdArgs);
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index a9d76c3..0eb1169 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -908,6 +908,7 @@
.Case("enumerator_attributes", true)
.Case("memory_sanitizer", LangOpts.Sanitize.Memory)
.Case("thread_sanitizer", LangOpts.Sanitize.Thread)
+ .Case("dataflow_sanitizer", LangOpts.Sanitize.DataFlow)
// Objective-C features
.Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
.Case("objc_arc", LangOpts.ObjCAutoRefCount)