[Driver] Add Scudo as a possible -fsanitize= option

Summary:
This change adds Scudo as a possible Sanitizer option via -fsanitize=.
This allows for easier static & shared linking of the Scudo library, it allows
us to enforce PIE (otherwise the security of the allocator is moot), and check
for incompatible Sanitizers combo.

In its current form, Scudo is not compatible with any other Sanitizer, but the
plan is to make it work in conjunction with UBsan (-fsanitize=scudo,undefined),
which will require additional work outside of the scope of this change.

Reviewers: eugenis, kcc, alekseyshl

Reviewed By: eugenis, alekseyshl

Subscribers: llvm-commits, srhines

Differential Revision: https://reviews.llvm.org/D39334

llvm-svn: 317337
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 32c1c43..8d9f32f 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -30,7 +30,7 @@
   NeedsUbsanCxxRt = Vptr | CFI,
   NotAllowedWithTrap = Vptr,
   NotAllowedWithMinimalRuntime = Vptr,
-  RequiresPIE = DataFlow,
+  RequiresPIE = DataFlow | Scudo,
   NeedsUnwindTables = Address | Thread | Memory | DataFlow,
   SupportsCoverage = Address | KernelAddress | Memory | Leak | Undefined |
                      Integer | Nullability | DataFlow | Fuzzer | FuzzerNoLink,
@@ -173,7 +173,7 @@
 bool SanitizerArgs::needsUbsanRt() const {
   // All of these include ubsan.
   if (needsAsanRt() || needsMsanRt() || needsTsanRt() || needsDfsanRt() ||
-      needsLsanRt() || needsCfiDiagRt())
+      needsLsanRt() || needsCfiDiagRt() || needsScudoRt())
     return false;
 
   return (Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) ||
@@ -370,17 +370,14 @@
 
   // Warn about incompatible groups of sanitizers.
   std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
-      std::make_pair(Address, Thread), std::make_pair(Address, Memory),
-      std::make_pair(Thread, Memory), std::make_pair(Leak, Thread),
-      std::make_pair(Leak, Memory), std::make_pair(KernelAddress, Address),
-      std::make_pair(KernelAddress, Leak),
-      std::make_pair(KernelAddress, Thread),
-      std::make_pair(KernelAddress, Memory),
-      std::make_pair(Efficiency, Address),
-      std::make_pair(Efficiency, Leak),
-      std::make_pair(Efficiency, Thread),
-      std::make_pair(Efficiency, Memory),
-      std::make_pair(Efficiency, KernelAddress)};
+      std::make_pair(Address, Thread | Memory),
+      std::make_pair(Thread, Memory),
+      std::make_pair(Leak, Thread | Memory),
+      std::make_pair(KernelAddress, Address| Leak | Thread | Memory),
+      std::make_pair(Efficiency, Address | Leak | Thread | Memory |
+                                 KernelAddress),
+      std::make_pair(Scudo, Address | Leak | Thread | Memory | KernelAddress |
+                            Efficiency) };
   for (auto G : IncompatibleGroups) {
     SanitizerMask Group = G.first;
     if (Kinds & Group) {