Merge remote-tracking branch 'origin/swift-4.1-branch' into stable
diff --git a/lib/asan/asan_descriptions.cc b/lib/asan/asan_descriptions.cc
index 822a6a6..5662e6b 100644
--- a/lib/asan/asan_descriptions.cc
+++ b/lib/asan/asan_descriptions.cc
@@ -150,7 +150,7 @@
   str.append(" %zu-byte region [%p,%p)\n", descr.chunk_size,
              (void *)descr.chunk_begin,
              (void *)(descr.chunk_begin + descr.chunk_size));
-  str.append("%s", d.EndLocation());
+  str.append("%s", d.Default());
   Printf("%s", str.data());
 }
 
@@ -260,7 +260,7 @@
     // FIXME: we may want to also print the size of the access here,
     // but in case of accesses generated by memset it may be confusing.
     str.append("%s <== Memory access at offset %zd %s this variable%s\n",
-               d.Location(), addr, pos_descr, d.EndLocation());
+               d.Location(), addr, pos_descr, d.Default());
   } else {
     str.append("\n");
   }
@@ -295,7 +295,7 @@
              MaybeDemangleGlobalName(g.name));
   PrintGlobalLocation(&str, g);
   str.append("' (0x%zx) of size %zu\n", g.beg, g.size);
-  str.append("%s", d.EndLocation());
+  str.append("%s", d.Default());
   PrintGlobalNameIfASCII(&str, g);
   Printf("%s", str.data());
 }
@@ -343,10 +343,10 @@
          ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
 
   if (!frame_descr) {
-    Printf("%s\n", d.EndLocation());
+    Printf("%s\n", d.Default());
     return;
   }
-  Printf(" at offset %zu in frame%s\n", offset, d.EndLocation());
+  Printf(" at offset %zu in frame%s\n", offset, d.Default());
 
   // Now we print the frame where the alloca has happened.
   // We print this frame as a stack trace with one element.
@@ -355,7 +355,7 @@
   // previously. That's unfortunate, but I have no better solution,
   // especially given that the alloca may be from entirely different place
   // (e.g. use-after-scope, or different thread's stack).
-  Printf("%s", d.EndLocation());
+  Printf("%s", d.Default());
   StackTrace alloca_stack(&frame_pc, 1);
   alloca_stack.Print();
 
@@ -405,18 +405,18 @@
     Printf("%sfreed by thread T%d%s here:%s\n", d.Allocation(),
            free_thread->tid,
            ThreadNameWithParenthesis(free_thread, tname, sizeof(tname)),
-           d.EndAllocation());
+           d.Default());
     StackTrace free_stack = GetStackTraceFromId(free_stack_id);
     free_stack.Print();
     Printf("%spreviously allocated by thread T%d%s here:%s\n", d.Allocation(),
            alloc_thread->tid,
            ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)),
-           d.EndAllocation());
+           d.Default());
   } else {
     Printf("%sallocated by thread T%d%s here:%s\n", d.Allocation(),
            alloc_thread->tid,
            ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)),
-           d.EndAllocation());
+           d.Default());
   }
   alloc_stack.Print();
   DescribeThread(GetCurrentThread());
diff --git a/lib/asan/asan_descriptions.h b/lib/asan/asan_descriptions.h
index 0ee677e..5161715 100644
--- a/lib/asan/asan_descriptions.h
+++ b/lib/asan/asan_descriptions.h
@@ -34,11 +34,8 @@
  public:
   Decorator() : SanitizerCommonDecorator() {}
   const char *Access() { return Blue(); }
-  const char *EndAccess() { return Default(); }
   const char *Location() { return Green(); }
-  const char *EndLocation() { return Default(); }
   const char *Allocation() { return Magenta(); }
-  const char *EndAllocation() { return Default(); }
 
   const char *ShadowByte(u8 byte) {
     switch (byte) {
@@ -72,9 +69,7 @@
         return Default();
     }
   }
-  const char *EndShadowByte() { return Default(); }
   const char *MemoryByte() { return Magenta(); }
-  const char *EndMemoryByte() { return Default(); }
 };
 
 enum ShadowKind : u8 {
diff --git a/lib/asan/asan_errors.cc b/lib/asan/asan_errors.cc
index b7a38eb..63aaab1 100644
--- a/lib/asan/asan_errors.cc
+++ b/lib/asan/asan_errors.cc
@@ -29,7 +29,7 @@
       "ERROR: AddressSanitizer: %s on address %p"
       " (pc %p bp %p sp %p T%d)\n", scariness.GetDescription(),
       (void *)addr, (void *)pc, (void *)bp, (void *)sp, tid);
-  Printf("%s", d.EndWarning());
+  Printf("%s", d.Default());
   scariness.Print();
   BufferedStackTrace stack;
   GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context,
@@ -77,7 +77,7 @@
       "ERROR: AddressSanitizer: %s on unknown address %p (pc %p bp %p sp %p "
       "T%d)\n",
       description, (void *)addr, (void *)pc, (void *)bp, (void *)sp, tid);
-  Printf("%s", d.EndWarning());
+  Printf("%s", d.Default());
   if (pc < GetPageSizeCached()) Report("Hint: pc points to the zero page.\n");
   if (is_memory_access) {
     const char *access_type =
@@ -109,7 +109,7 @@
       "thread T%d%s:\n",
       scariness.GetDescription(), addr_description.addr, tid,
       ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
-  Printf("%s", d.EndWarning());
+  Printf("%s", d.Default());
   scariness.Print();
   GET_STACK_TRACE_FATAL(second_free_stack->trace[0],
                         second_free_stack->top_frame_bp);
@@ -127,7 +127,7 @@
       "T%d%s:\n",
       scariness.GetDescription(), addr_description.addr, tid,
       ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
-  Printf("%s  object passed to delete has wrong type:\n", d.EndWarning());
+  Printf("%s  object passed to delete has wrong type:\n", d.Default());
   Printf(
       "  size of the allocated type:   %zd bytes;\n"
       "  size of the deallocated type: %zd bytes.\n",
@@ -152,7 +152,7 @@
       "which was not malloc()-ed: %p in thread T%d%s\n",
       addr_description.Address(), tid,
       ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
-  Printf("%s", d.EndWarning());
+  Printf("%s", d.Default());
   CHECK_GT(free_stack->size, 0);
   scariness.Print();
   GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
@@ -173,7 +173,7 @@
          scariness.GetDescription(),
          alloc_names[alloc_type], dealloc_names[dealloc_type],
          addr_description.addr);
-  Printf("%s", d.EndWarning());
+  Printf("%s", d.Default());
   CHECK_GT(dealloc_stack->size, 0);
   scariness.Print();
   GET_STACK_TRACE_FATAL(dealloc_stack->trace[0], dealloc_stack->top_frame_bp);
@@ -192,7 +192,7 @@
       "ERROR: AddressSanitizer: attempting to call malloc_usable_size() for "
       "pointer which is not owned: %p\n",
       addr_description.Address());
-  Printf("%s", d.EndWarning());
+  Printf("%s", d.Default());
   stack->Print();
   addr_description.Print();
   ReportErrorSummary(scariness.GetDescription(), stack);
@@ -205,7 +205,7 @@
       "ERROR: AddressSanitizer: attempting to call "
       "__sanitizer_get_allocated_size() for pointer which is not owned: %p\n",
       addr_description.Address());
-  Printf("%s", d.EndWarning());
+  Printf("%s", d.Default());
   stack->Print();
   addr_description.Print();
   ReportErrorSummary(scariness.GetDescription(), stack);
@@ -222,7 +222,7 @@
       bug_type, addr1_description.Address(),
       addr1_description.Address() + length1, addr2_description.Address(),
       addr2_description.Address() + length2);
-  Printf("%s", d.EndWarning());
+  Printf("%s", d.Default());
   scariness.Print();
   stack->Print();
   addr1_description.Print();
@@ -235,7 +235,7 @@
   Printf("%s", d.Warning());
   Report("ERROR: AddressSanitizer: %s: (size=%zd)\n",
          scariness.GetDescription(), size);
-  Printf("%s", d.EndWarning());
+  Printf("%s", d.Default());
   scariness.Print();
   stack->Print();
   addr_description.Print();
@@ -263,7 +263,7 @@
   Printf("%s", d.Warning());
   Report("ERROR: AddressSanitizer: %s (%p):\n", scariness.GetDescription(),
          global1.beg);
-  Printf("%s", d.EndWarning());
+  Printf("%s", d.Default());
   InternalScopedString g1_loc(256), g2_loc(256);
   PrintGlobalLocation(&g1_loc, global1);
   PrintGlobalLocation(&g2_loc, global2);
@@ -292,7 +292,7 @@
   Printf("%s", d.Warning());
   Report("ERROR: AddressSanitizer: %s: %p %p\n", scariness.GetDescription(),
          addr1_description.Address(), addr2_description.Address());
-  Printf("%s", d.EndWarning());
+  Printf("%s", d.Default());
   GET_STACK_TRACE_FATAL(pc, bp);
   stack.Print();
   addr1_description.Print();
@@ -491,13 +491,13 @@
   uptr addr = addr_description.Address();
   Report("ERROR: AddressSanitizer: %s on address %p at pc %p bp %p sp %p\n",
          bug_descr, (void *)addr, pc, bp, sp);
-  Printf("%s", d.EndWarning());
+  Printf("%s", d.Default());
 
   char tname[128];
   Printf("%s%s of size %zu at %p thread T%d%s%s\n", d.Access(),
          access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", access_size,
          (void *)addr, tid,
-         ThreadNameWithParenthesis(tid, tname, sizeof(tname)), d.EndAccess());
+         ThreadNameWithParenthesis(tid, tname, sizeof(tname)), d.Default());
 
   scariness.Print();
   GET_STACK_TRACE_FATAL(pc, bp);
diff --git a/lib/asan/asan_report.cc b/lib/asan/asan_report.cc
index 2e477f2..cd8a4f0 100644
--- a/lib/asan/asan_report.cc
+++ b/lib/asan/asan_report.cc
@@ -60,9 +60,8 @@
                      bool in_shadow, const char *after) {
   Decorator d;
   str->append("%s%s%x%x%s%s", before,
-              in_shadow ? d.ShadowByte(byte) : d.MemoryByte(),
-              byte >> 4, byte & 15,
-              in_shadow ? d.EndShadowByte() : d.EndMemoryByte(), after);
+              in_shadow ? d.ShadowByte(byte) : d.MemoryByte(), byte >> 4,
+              byte & 15, d.Default(), after);
 }
 
 static void PrintZoneForPointer(uptr ptr, uptr zone_ptr,
diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc
index c121e6a..a792768 100644
--- a/lib/lsan/lsan_common.cc
+++ b/lib/lsan/lsan_common.cc
@@ -122,7 +122,6 @@
   Decorator() : SanitizerCommonDecorator() { }
   const char *Error() { return Red(); }
   const char *Leak() { return Blue(); }
-  const char *End() { return Default(); }
 };
 
 static inline bool CanBeAHeapPointer(uptr p) {
@@ -564,7 +563,7 @@
            "\n");
     Printf("%s", d.Error());
     Report("ERROR: LeakSanitizer: detected memory leaks\n");
-    Printf("%s", d.End());
+    Printf("%s", d.Default());
     param.leak_report.ReportTopLeaks(flags()->max_leaks);
   }
   if (common_flags()->print_suppressions)
@@ -698,7 +697,7 @@
   Printf("%s leak of %zu byte(s) in %zu object(s) allocated from:\n",
          leaks_[index].is_directly_leaked ? "Direct" : "Indirect",
          leaks_[index].total_size, leaks_[index].hit_count);
-  Printf("%s", d.End());
+  Printf("%s", d.Default());
 
   PrintStackTraceById(leaks_[index].stack_trace_id);
 
diff --git a/lib/msan/msan_report.cc b/lib/msan/msan_report.cc
index 9a35c9c..cddad01 100644
--- a/lib/msan/msan_report.cc
+++ b/lib/msan/msan_report.cc
@@ -30,10 +30,8 @@
 class Decorator: public __sanitizer::SanitizerCommonDecorator {
  public:
   Decorator() : SanitizerCommonDecorator() { }
-  const char *Warning()    { return Red(); }
   const char *Origin()     { return Magenta(); }
   const char *Name()   { return Green(); }
-  const char *End()    { return Default(); }
 };
 
 static void DescribeStackOrigin(const char *so, uptr pc) {
@@ -47,7 +45,7 @@
       "  %sUninitialized value was created by an allocation of '%s%s%s'"
       " in the stack frame of function '%s%s%s'%s\n",
       d.Origin(), d.Name(), s, d.Origin(), d.Name(), sep + 1, d.Origin(),
-      d.End());
+      d.Default());
   InternalFree(s);
 
   if (pc) {
@@ -66,7 +64,7 @@
     StackTrace stack;
     o = o.getNextChainedOrigin(&stack);
     Printf("  %sUninitialized value was stored to memory at%s\n", d.Origin(),
-        d.End());
+           d.Default());
     stack.Print();
   }
   if (o.isStackOrigin()) {
@@ -78,18 +76,19 @@
     switch (stack.tag) {
       case StackTrace::TAG_ALLOC:
         Printf("  %sUninitialized value was created by a heap allocation%s\n",
-               d.Origin(), d.End());
+               d.Origin(), d.Default());
         break;
       case StackTrace::TAG_DEALLOC:
         Printf("  %sUninitialized value was created by a heap deallocation%s\n",
-               d.Origin(), d.End());
+               d.Origin(), d.Default());
         break;
       case STACK_TRACE_TAG_POISON:
         Printf("  %sMemory was marked as uninitialized%s\n", d.Origin(),
-               d.End());
+               d.Default());
         break;
       default:
-        Printf("  %sUninitialized value was created%s\n", d.Origin(), d.End());
+        Printf("  %sUninitialized value was created%s\n", d.Origin(),
+               d.Default());
         break;
     }
     stack.Print();
@@ -104,7 +103,7 @@
   Decorator d;
   Printf("%s", d.Warning());
   Report("WARNING: MemorySanitizer: use-of-uninitialized-value\n");
-  Printf("%s", d.End());
+  Printf("%s", d.Default());
   stack->Print();
   if (origin) {
     DescribeOrigin(origin);
@@ -144,7 +143,7 @@
     Decorator d;
     Printf("%s", d.Warning());
     Printf("MemorySanitizer: %d warnings reported.\n", msan_report_count);
-    Printf("%s", d.End());
+    Printf("%s", d.Default());
   }
 }
 
@@ -203,7 +202,7 @@
   Decorator d;
   Printf("%s", d.Warning());
   Printf("Shadow map of [%p, %p), %zu bytes:\n", start, end, end - start);
-  Printf("%s", d.End());
+  Printf("%s", d.Default());
   while (s < e) {
     // Line start.
     if (pos % 16 == 0) {
@@ -265,7 +264,7 @@
   Printf("%s", d.Warning());
   Printf("%sUninitialized bytes in %s%s%s at offset %zu inside [%p, %zu)%s\n",
          d.Warning(), d.Name(), what, d.Warning(), offset, start, size,
-         d.End());
+         d.Default());
   if (__sanitizer::Verbosity())
     DescribeMemoryRange(start, size);
 }
diff --git a/lib/sanitizer_common/CMakeLists.txt b/lib/sanitizer_common/CMakeLists.txt
index a17bd12..b28aea4 100644
--- a/lib/sanitizer_common/CMakeLists.txt
+++ b/lib/sanitizer_common/CMakeLists.txt
@@ -191,6 +191,21 @@
   CFLAGS ${SANITIZER_CFLAGS}
   DEFS ${SANITIZER_COMMON_DEFINITIONS})
 
+set(SANITIZER_NO_WEAK_HOOKS_CFLAGS ${SANITIZER_CFLAGS})
+list(APPEND SANITIZER_NO_WEAK_HOOKS_CFLAGS "-DSANITIZER_SUPPORTS_WEAK_HOOKS=0")
+add_compiler_rt_object_libraries(RTSanitizerCommonNoHooks
+  ${OS_OPTION}
+  ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
+  SOURCES ${SANITIZER_SOURCES}
+  CFLAGS ${SANITIZER_NO_WEAK_HOOKS_CFLAGS}
+  DEFS ${SANITIZER_COMMON_DEFINITIONS})
+add_compiler_rt_object_libraries(RTSanitizerCommonLibcNoHooks
+  ${OS_OPTION}
+  ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
+  SOURCES ${SANITIZER_LIBCDEP_SOURCES}
+  CFLAGS ${SANITIZER_NO_WEAK_HOOKS_CFLAGS}
+  DEFS ${SANITIZER_COMMON_DEFINITIONS})
+
 if(WIN32)
   add_compiler_rt_object_libraries(SanitizerCommonWeakInterception
     ${SANITIZER_COMMON_SUPPORTED_OS}
diff --git a/lib/sanitizer_common/sanitizer_internal_defs.h b/lib/sanitizer_common/sanitizer_internal_defs.h
index f35b095..9931bf1 100644
--- a/lib/sanitizer_common/sanitizer_internal_defs.h
+++ b/lib/sanitizer_common/sanitizer_internal_defs.h
@@ -56,11 +56,13 @@
 
 // SANITIZER_SUPPORTS_WEAK_HOOKS means that we support real weak functions that
 // will evaluate to a null pointer when not defined.
+#ifndef SANITIZER_SUPPORTS_WEAK_HOOKS
 #if (SANITIZER_LINUX || SANITIZER_MAC) && !SANITIZER_GO
 # define SANITIZER_SUPPORTS_WEAK_HOOKS 1
 #else
 # define SANITIZER_SUPPORTS_WEAK_HOOKS 0
 #endif
+#endif // SANITIZER_SUPPORTS_WEAK_HOOKS
 // For some weak hooks that will be called very often and we want to avoid the
 // overhead of executing the default implementation when it is not necessary,
 // we can use the flag SANITIZER_SUPPORTS_WEAK_HOOKS to only define the default
diff --git a/lib/sanitizer_common/sanitizer_report_decorator.h b/lib/sanitizer_common/sanitizer_report_decorator.h
index 86536aa..daa7f00 100644
--- a/lib/sanitizer_common/sanitizer_report_decorator.h
+++ b/lib/sanitizer_common/sanitizer_report_decorator.h
@@ -27,8 +27,8 @@
   SanitizerCommonDecorator() : ansi_(ColorizeReports()) {}
   const char *Bold()    const { return ansi_ ? "\033[1m" : ""; }
   const char *Default() const { return ansi_ ? "\033[1m\033[0m"  : ""; }
-  const char *Warning()    { return Red(); }
-  const char *EndWarning() { return Default(); }
+  const char *Warning() const { return Red(); }
+
  protected:
   const char *Black()   const { return ansi_ ? "\033[1m\033[30m" : ""; }
   const char *Red()     const { return ansi_ ? "\033[1m\033[31m" : ""; }
diff --git a/lib/tsan/rtl/tsan_report.cc b/lib/tsan/rtl/tsan_report.cc
index 32cc332..3b11797 100644
--- a/lib/tsan/rtl/tsan_report.cc
+++ b/lib/tsan/rtl/tsan_report.cc
@@ -38,18 +38,11 @@
 class Decorator: public __sanitizer::SanitizerCommonDecorator {
  public:
   Decorator() : SanitizerCommonDecorator() { }
-  const char *Warning()    { return Red(); }
-  const char *EndWarning() { return Default(); }
   const char *Access()     { return Blue(); }
-  const char *EndAccess()  { return Default(); }
   const char *ThreadDescription()    { return Cyan(); }
-  const char *EndThreadDescription() { return Default(); }
   const char *Location()   { return Green(); }
-  const char *EndLocation() { return Default(); }
   const char *Sleep()   { return Yellow(); }
-  const char *EndSleep() { return Default(); }
   const char *Mutex()   { return Magenta(); }
-  const char *EndMutex() { return Default(); }
 };
 
 ReportDesc::ReportDesc()
@@ -180,7 +173,7 @@
   }
   PrintMutexSet(mop->mset);
   Printf(":\n");
-  Printf("%s", d.EndAccess());
+  Printf("%s", d.Default());
   PrintStack(mop->stack);
 }
 
@@ -221,20 +214,20 @@
         loc->fd, thread_name(thrbuf, loc->tid));
     print_stack = true;
   }
-  Printf("%s", d.EndLocation());
+  Printf("%s", d.Default());
   if (print_stack)
     PrintStack(loc->stack);
 }
 
 static void PrintMutexShort(const ReportMutex *rm, const char *after) {
   Decorator d;
-  Printf("%sM%zd%s%s", d.Mutex(), rm->id, d.EndMutex(), after);
+  Printf("%sM%zd%s%s", d.Mutex(), rm->id, d.Default(), after);
 }
 
 static void PrintMutexShortWithAddress(const ReportMutex *rm,
                                        const char *after) {
   Decorator d;
-  Printf("%sM%zd (%p)%s%s", d.Mutex(), rm->id, rm->addr, d.EndMutex(), after);
+  Printf("%sM%zd (%p)%s%s", d.Mutex(), rm->id, rm->addr, d.Default(), after);
 }
 
 static void PrintMutex(const ReportMutex *rm) {
@@ -242,11 +235,11 @@
   if (rm->destroyed) {
     Printf("%s", d.Mutex());
     Printf("  Mutex M%llu is already destroyed.\n\n", rm->id);
-    Printf("%s", d.EndMutex());
+    Printf("%s", d.Default());
   } else {
     Printf("%s", d.Mutex());
     Printf("  Mutex M%llu (%p) created at:\n", rm->id, rm->addr);
-    Printf("%s", d.EndMutex());
+    Printf("%s", d.Default());
     PrintStack(rm->stack);
   }
 }
@@ -264,7 +257,7 @@
   if (rt->workerthread) {
     Printf(" (tid=%zu, %s) is a GCD worker thread\n", rt->os_id, thread_status);
     Printf("\n");
-    Printf("%s", d.EndThreadDescription());
+    Printf("%s", d.Default());
     return;
   }
   Printf(" (tid=%zu, %s) created by %s", rt->os_id, thread_status,
@@ -272,7 +265,7 @@
   if (rt->stack)
     Printf(" at:");
   Printf("\n");
-  Printf("%s", d.EndThreadDescription());
+  Printf("%s", d.Default());
   PrintStack(rt->stack);
 }
 
@@ -280,7 +273,7 @@
   Decorator d;
   Printf("%s", d.Sleep());
   Printf("  As if synchronized via sleep:\n");
-  Printf("%s", d.EndSleep());
+  Printf("%s", d.Default());
   PrintStack(s);
 }
 
@@ -324,7 +317,7 @@
   Printf("%s", d.Warning());
   Printf("WARNING: ThreadSanitizer: %s (pid=%d)\n", rep_typ_str,
          (int)internal_getpid());
-  Printf("%s", d.EndWarning());
+  Printf("%s", d.Default());
 
   if (rep->typ == ReportTypeDeadlock) {
     char thrbuf[kThreadBufSize];
@@ -342,7 +335,7 @@
       PrintMutexShort(rep->mutexes[i], " in ");
       Printf("%s", d.ThreadDescription());
       Printf("%s:\n", thread_name(thrbuf, rep->unique_tids[i]));
-      Printf("%s", d.EndThreadDescription());
+      Printf("%s", d.Default());
       if (flags()->second_deadlock_stack) {
         PrintStack(rep->stacks[2*i]);
         Printf("  Mutex ");
diff --git a/lib/ubsan/CMakeLists.txt b/lib/ubsan/CMakeLists.txt
index 457a6b4..1b1bad1 100644
--- a/lib/ubsan/CMakeLists.txt
+++ b/lib/ubsan/CMakeLists.txt
@@ -74,6 +74,18 @@
                   RTSanitizerCommonLibc
       LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
       PARENT_TARGET ubsan)
+
+    add_compiler_rt_runtime(clang_rt.ubsan
+      STATIC
+      OS ${SANITIZER_COMMON_SUPPORTED_OS}
+      ARCHS ${UBSAN_SUPPORTED_ARCH}
+      OBJECT_LIBS RTUbsan
+                  RTUbsan_standalone
+                  RTSanitizerCommonNoHooks
+                  RTSanitizerCommonLibcNoHooks
+                  RTInterception
+      LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
+      PARENT_TARGET ubsan)
   endif()
 
 else()
diff --git a/lib/ubsan/ubsan_diag.cc b/lib/ubsan/ubsan_diag.cc
index 742802b..f039a31 100644
--- a/lib/ubsan/ubsan_diag.cc
+++ b/lib/ubsan/ubsan_diag.cc
@@ -97,9 +97,7 @@
  public:
   Decorator() : SanitizerCommonDecorator() {}
   const char *Highlight() const { return Green(); }
-  const char *EndHighlight() const { return Default(); }
   const char *Note() const { return Black(); }
-  const char *EndNote() const { return Default(); }
 };
 }
 
@@ -295,7 +293,7 @@
     Buffer.append("%c", P == Loc ? '^' : Byte);
     Buffer.append("%c", Byte);
   }
-  Buffer.append("%s\n", Decor.EndHighlight());
+  Buffer.append("%s\n", Decor.Default());
 
   // Go over the line again, and print names for the ranges.
   InRange = 0;
@@ -345,12 +343,12 @@
 
   switch (Level) {
   case DL_Error:
-    Buffer.append("%s runtime error: %s%s", Decor.Warning(), Decor.EndWarning(),
+    Buffer.append("%s runtime error: %s%s", Decor.Warning(), Decor.Default(),
                   Decor.Bold());
     break;
 
   case DL_Note:
-    Buffer.append("%s note: %s", Decor.Note(), Decor.EndNote());
+    Buffer.append("%s note: %s", Decor.Note(), Decor.Default());
     break;
   }
 
diff --git a/lib/ubsan/ubsan_diag_standalone.cc b/lib/ubsan/ubsan_diag_standalone.cc
index df8ed5f..1f4a5bd 100644
--- a/lib/ubsan/ubsan_diag_standalone.cc
+++ b/lib/ubsan/ubsan_diag_standalone.cc
@@ -26,9 +26,10 @@
   if (request_fast_unwind)
     __sanitizer::GetThreadStackTopAndBottom(false, &top, &bottom);
 
-  GET_REPORT_OPTIONS(false);
+  GET_CURRENT_PC_BP_SP;
+  (void)sp;
   BufferedStackTrace stack;
-  stack.Unwind(kStackTraceMax, Opts.pc, Opts.bp, nullptr, top, bottom,
+  stack.Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom,
                request_fast_unwind);
   stack.Print();
 }
diff --git a/lib/ubsan/ubsan_init.cc b/lib/ubsan/ubsan_init.cc
index 307bca3..d7433a5 100644
--- a/lib/ubsan/ubsan_init.cc
+++ b/lib/ubsan/ubsan_init.cc
@@ -40,8 +40,8 @@
 
 static void CommonStandaloneInit() {
   SanitizerToolName = GetSanititizerToolName();
-  InitializeFlags();
   CacheBinaryName();
+  InitializeFlags();
   __sanitizer_set_report_path(common_flags()->log_path);
   AndroidLogInit();
   InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
diff --git a/test/ubsan/CMakeLists.txt b/test/ubsan/CMakeLists.txt
index f4b73e8..ef406eb 100644
--- a/test/ubsan/CMakeLists.txt
+++ b/test/ubsan/CMakeLists.txt
@@ -40,6 +40,15 @@
   endif()
 endforeach()
 
+if(APPLE)
+  foreach(arch ${UBSAN_TEST_ARCH})
+    set(UBSAN_TEST_TARGET_ARCH ${arch})
+    get_test_cc_for_arch(${arch} UBSAN_TEST_TARGET_CC UBSAN_TEST_TARGET_CFLAGS)
+    set(UBSAN_TEST_TARGET_CFLAGS "${UBSAN_TEST_TARGET_CFLAGS} -lc++abi")
+    add_ubsan_testsuite("StandaloneStatic" ubsan ${arch})
+  endforeach()
+endif()
+
 add_lit_testsuite(check-ubsan "Running UndefinedBehaviorSanitizer tests"
   ${UBSAN_TESTSUITES}
   DEPENDS ${UBSAN_TEST_DEPS})
diff --git a/test/ubsan/TestCases/Misc/coverage-levels.cc b/test/ubsan/TestCases/Misc/coverage-levels.cc
index f96b487..05c1993 100644
--- a/test/ubsan/TestCases/Misc/coverage-levels.cc
+++ b/test/ubsan/TestCases/Misc/coverage-levels.cc
@@ -22,6 +22,7 @@
 
 // Coverage is not yet implemented in TSan.
 // XFAIL: ubsan-tsan
+// UNSUPPORTED: ubsan-standalone-static
 
 volatile int sink;
 int main(int argc, char **argv) {
diff --git a/test/ubsan/TestCases/TypeCheck/Linux/PR33221.cpp b/test/ubsan/TestCases/TypeCheck/Linux/PR33221.cpp
index e026e8d..a5e61c2 100644
--- a/test/ubsan/TestCases/TypeCheck/Linux/PR33221.cpp
+++ b/test/ubsan/TestCases/TypeCheck/Linux/PR33221.cpp
@@ -22,7 +22,7 @@
 int main() {
   int page_size = getpagesize();
 
-  void *non_accessible = mmap(nullptr, page_size, PROT_NONE,
+  void *non_accessible = mmap(nullptr, page_size * 2, PROT_NONE,
                               MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   
   if (non_accessible == MAP_FAILED)
diff --git a/test/ubsan/lit.common.cfg b/test/ubsan/lit.common.cfg
index b55fb5f..616637b 100644
--- a/test/ubsan/lit.common.cfg
+++ b/test/ubsan/lit.common.cfg
@@ -21,6 +21,10 @@
   config.name = 'UBSan-Standalone-' + config.target_arch
   config.available_features.add("ubsan-standalone")
   clang_ubsan_cflags = []
+elif ubsan_lit_test_mode == "StandaloneStatic":
+  config.name = 'UBSan-StandaloneStatic-' + config.target_arch
+  config.available_features.add("ubsan-standalone-static")
+  clang_ubsan_cflags = ['-static-libsan']
 elif ubsan_lit_test_mode == "AddressSanitizer":
   config.name = 'UBSan-ASan-' + config.target_arch
   config.available_features.add("ubsan-asan")