[ubsan] Null-check pointers in -fsanitize=vptr (PR33881)

The instrumentation generated by -fsanitize=vptr does not null check a
user pointer before loading from it. This causes crashes in the face of
UB member calls (this=nullptr), i.e it's causing user programs to crash
only after UBSan is turned on.

The fix is to make run-time null checking a prerequisite for enabling
-fsanitize=vptr, and to then teach UBSan to reuse these run-time null
checks to make -fsanitize=vptr safe.

Testing: check-clang, check-ubsan, a stage2 ubsan-enabled build

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

https://bugs.llvm.org/show_bug.cgi?id=33881

llvm-svn: 309007
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index f119174..41f6d19 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -306,6 +306,13 @@
     Kinds &= ~Vptr;
   }
 
+  // Disable -fsanitize=vptr if -fsanitize=null is not enabled (the vptr
+  // instrumentation is broken without run-time null checks).
+  if ((Kinds & Vptr) && !(Kinds & Null)) {
+    Kinds &= ~Vptr;
+    D.Diag(diag::warn_drv_disabling_vptr_no_null_check);
+  }
+
   // Check that LTO is enabled if we need it.
   if ((Kinds & NeedsLTO) && !D.isUsingLTO()) {
     D.Diag(diag::err_drv_argument_only_allowed_with)