Allow UBSan+MSan and UBSan+TSan combinations (Clang part).

Embed UBSan runtime into TSan and MSan runtimes in the same as we do
in ASan. Extend UBSan test suite to also run tests for these
combinations.

llvm-svn: 235953
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index cd3785c..f453208 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -160,7 +160,9 @@
 
 bool SanitizerArgs::needsUbsanRt() const {
   return !UbsanTrapOnError && hasOneOf(Sanitizers, NeedsUbsanRt) &&
-         !Sanitizers.has(SanitizerKind::Address);
+         !Sanitizers.has(SanitizerKind::Address) &&
+         !Sanitizers.has(SanitizerKind::Memory) &&
+         !Sanitizers.has(SanitizerKind::Thread);
 }
 
 bool SanitizerArgs::requiresPIE() const {
@@ -284,9 +286,7 @@
       std::make_pair(SanitizeKind::Address, SanitizeKind::Memory),
       std::make_pair(SanitizeKind::Thread, SanitizeKind::Memory),
       std::make_pair(SanitizeKind::Leak, SanitizeKind::Thread),
-      std::make_pair(SanitizeKind::Leak, SanitizeKind::Memory),
-      std::make_pair(SanitizeKind::NeedsUbsanRt, SanitizeKind::Thread),
-      std::make_pair(SanitizeKind::NeedsUbsanRt, SanitizeKind::Memory)};
+      std::make_pair(SanitizeKind::Leak, SanitizeKind::Memory)};
   for (auto G : IncompatibleGroups) {
     uint64_t Group = G.first;
     if (Kinds & Group) {
diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c
index 994b2b2..280b6e6 100644
--- a/clang/test/Driver/fsanitize.c
+++ b/clang/test/Driver/fsanitize.c
@@ -57,9 +57,6 @@
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=leak,memory -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANL-SANM
 // CHECK-SANL-SANM: '-fsanitize=leak' not allowed with '-fsanitize=memory'
 
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=signed-integer-overflow,memory -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-UBSAN
-// CHECK-MSAN-UBSAN: '-fsanitize=signed-integer-overflow' not allowed with '-fsanitize=memory'
-
 // RUN: %clang -target x86_64-linux-gnu -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-TRACK-ORIGINS
 // CHECK-ONLY-TRACK-ORIGINS: warning: argument unused during compilation: '-fsanitize-memory-track-origins'
 
diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c
index 7cbc37f..5fef817 100644
--- a/clang/test/Driver/sanitizer-ld.c
+++ b/clang/test/Driver/sanitizer-ld.c
@@ -244,6 +244,22 @@
 // CHECK-ASAN-UBSAN-LINUX-CXX: "-lstdc++"
 // CHECK-ASAN-UBSAN-LINUX-CXX: "-lpthread"
 
+// RUN: %clangxx -fsanitize=memory,undefined %s -### -o %t.o 2>&1 \
+// RUN:     -target x86_64-unknown-linux \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-MSAN-UBSAN-LINUX-CXX %s
+// CHECK-MSAN-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}"
+// CHECK-MSAN-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.msan-x86_64.a" "-no-whole-archive"
+// CHECK-MSAN-UBSAN-LINUX-CXX-NOT: libclang_rt.ubsan
+
+// RUN: %clangxx -fsanitize=thread,undefined %s -### -o %t.o 2>&1 \
+// RUN:     -target x86_64-unknown-linux \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-TSAN-UBSAN-LINUX-CXX %s
+// CHECK-TSAN-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}"
+// CHECK-TSAN-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.tsan-x86_64.a" "-no-whole-archive"
+// CHECK-TSAN-UBSAN-LINUX-CXX-NOT: libclang_rt.ubsan
+
 // RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
 // RUN:     -target i386-unknown-linux \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \