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/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);