<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">+ Nico, sorry I missed your email in the reply-all. Here's a revised version of the warning:<div class=""><br class=""></div><div class=""><a href="https://reviews.llvm.org/D36096" class="">https://reviews.llvm.org/D36096</a></div><div class=""><br class=""></div><div class="">vedant</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jul 31, 2017, at 10:18 AM, Vedant Kumar via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">The bot should start working again with -fsanitize=vptr,null.<br class=""><br class="">The warning can be improved. If we find -fno-sanitize=null in the argument list, we might say:<br class="">implicitly disabling vptr sanitizer because "-fno-sanitize=null" was specified<br class=""><br class="">Otherwise we might say:<br class="">implicitly disabling vptr sanitizer because null checking wasn't enabled, try specifying -fsanitize=null or -fsanitize=undefined<br class=""><br class="">I'll send out a patch for review.<br class=""><br class="">vedant<br class=""><br class=""><blockquote type="cite" class="">On Jul 31, 2017, at 9:37 AM, Hans Wennborg <<a href="mailto:hans@chromium.org" class="">hans@chromium.org</a>> wrote:<br class=""><br class="">/sub<br class=""><br class="">I believe Vedant asked for this to be merged to 5.0, so I'd like to<br class="">merge the resolution too.<br class=""><br class="">On Mon, Jul 31, 2017 at 8:51 AM, Nico Weber via cfe-commits<br class=""><<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a>> wrote:<br class=""><blockquote type="cite" class="">Hi Vedant,<br class=""><br class="">after this change our ubsanvptr bot fails like so:<br class=""><br class="">clang-6.0: error: implicitly disabling vptr sanitizer because null checking<br class="">wasn't enabled [-Werror,-Wauto-disable-vptr-sanitizer]<br class=""><br class="">The bot uses -fsanitize=vptr. I have no idea what this warning is supposed<br class="">to tell me. Maybe it could be reworded, or maybe it shouldn't be emitted?<br class=""><br class="">Thanks,<br class="">Nico<br class=""><br class="">On Tue, Jul 25, 2017 at 3:34 PM, Vedant Kumar via cfe-commits<br class=""><<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a>> wrote:<br class=""><blockquote type="cite" class=""><br class="">Author: vedantk<br class="">Date: Tue Jul 25 12:34:23 2017<br class="">New Revision: 309007<br class=""><br class="">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=309007&view=rev" class="">http://llvm.org/viewvc/llvm-project?rev=309007&view=rev</a><br class="">Log:<br class="">[ubsan] Null-check pointers in -fsanitize=vptr (PR33881)<br class=""><br class="">The instrumentation generated by -fsanitize=vptr does not null check a<br class="">user pointer before loading from it. This causes crashes in the face of<br class="">UB member calls (this=nullptr), i.e it's causing user programs to crash<br class="">only after UBSan is turned on.<br class=""><br class="">The fix is to make run-time null checking a prerequisite for enabling<br class="">-fsanitize=vptr, and to then teach UBSan to reuse these run-time null<br class="">checks to make -fsanitize=vptr safe.<br class=""><br class="">Testing: check-clang, check-ubsan, a stage2 ubsan-enabled build<br class=""><br class="">Differential Revision: <a href="https://reviews.llvm.org/D35735" class="">https://reviews.llvm.org/D35735</a><br class=""><br class=""><a href="https://bugs.llvm.org/show_bug.cgi?id=33881" class="">https://bugs.llvm.org/show_bug.cgi?id=33881</a><br class=""><br class="">Modified:<br class="">   cfe/trunk/docs/ReleaseNotes.rst<br class="">   cfe/trunk/docs/UndefinedBehaviorSanitizer.rst<br class="">   cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td<br class="">   cfe/trunk/include/clang/Basic/DiagnosticGroups.td<br class="">   cfe/trunk/lib/CodeGen/CGExpr.cpp<br class="">   cfe/trunk/lib/Driver/SanitizerArgs.cpp<br class="">   cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp<br class="">   cfe/trunk/test/CodeGenCXX/ubsan-devirtualized-calls.cpp<br class="">   cfe/trunk/test/CodeGenCXX/ubsan-type-checks.cpp<br class="">   cfe/trunk/test/CodeGenCXX/ubsan-vtable-checks.cpp<br class="">   cfe/trunk/test/Driver/fsanitize.c<br class="">   cfe/trunk/test/Driver/rtti-options.cpp<br class=""><br class="">Modified: cfe/trunk/docs/ReleaseNotes.rst<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ReleaseNotes.rst?rev=309007&r1=309006&r2=309007&view=diff<br class=""><br class="">==============================================================================<br class="">--- cfe/trunk/docs/ReleaseNotes.rst (original)<br class="">+++ cfe/trunk/docs/ReleaseNotes.rst Tue Jul 25 12:34:23 2017<br class="">@@ -155,7 +155,9 @@ Static Analyzer<br class="">Undefined Behavior Sanitizer (UBSan)<br class="">------------------------------------<br class=""><br class="">-...<br class="">+The C++ dynamic type check now requires run-time null checking (i.e,<br class="">+`-fsanitize=vptr` cannot be used without `-fsanitize=null`). This change<br class="">does<br class="">+not impact users who rely on UBSan check groups (e.g<br class="">`-fsanitize=undefined`).<br class=""><br class="">Core Analysis Improvements<br class="">==========================<br class=""><br class="">Modified: cfe/trunk/docs/UndefinedBehaviorSanitizer.rst<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UndefinedBehaviorSanitizer.rst?rev=309007&r1=309006&r2=309007&view=diff<br class=""><br class="">==============================================================================<br class="">--- cfe/trunk/docs/UndefinedBehaviorSanitizer.rst (original)<br class="">+++ cfe/trunk/docs/UndefinedBehaviorSanitizer.rst Tue Jul 25 12:34:23 2017<br class="">@@ -130,11 +130,11 @@ Available checks are:<br class="">     it is often unintentional, so UBSan offers to catch it.<br class="">  -  ``-fsanitize=vla-bound``: A variable-length array whose bound<br class="">     does not evaluate to a positive value.<br class="">-  -  ``-fsanitize=vptr``: Use of an object whose vptr indicates that<br class="">-     it is of the wrong dynamic type, or that its lifetime has not<br class="">-     begun or has ended. Incompatible with ``-fno-rtti``. Link must<br class="">-     be performed by ``clang++``, not ``clang``, to make sure<br class="">C++-specific<br class="">-     parts of the runtime library and C++ standard libraries are present.<br class="">+  -  ``-fsanitize=vptr``: Use of an object whose vptr indicates that it<br class="">is of<br class="">+     the wrong dynamic type, or that its lifetime has not begun or has<br class="">ended.<br class="">+     Incompatible with ``-fno-rtti`` and ``-fno-sanitize=null``. Link<br class="">must be<br class="">+     performed by ``clang++``, not ``clang``, to make sure C++-specific<br class="">parts of<br class="">+     the runtime library and C++ standard libraries are present.<br class=""><br class="">You can also use the following check groups:<br class="">  -  ``-fsanitize=undefined``: All of the checks listed above other than<br class=""><br class="">Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td?rev=309007&r1=309006&r2=309007&view=diff<br class=""><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td (original)<br class="">+++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td Tue Jul 25<br class="">12:34:23 2017<br class="">@@ -230,7 +230,10 @@ def warn_drv_enabling_rtti_with_exceptio<br class="">  InGroup<DiagGroup<"rtti-for-exceptions">>;<br class="">def warn_drv_disabling_vptr_no_rtti_default : Warning<<br class="">  "implicitly disabling vptr sanitizer because rtti wasn't enabled">,<br class="">-  InGroup<DiagGroup<"auto-disable-vptr-sanitizer">>;<br class="">+  InGroup<AutoDisableVptrSanitizer>;<br class="">+def warn_drv_disabling_vptr_no_null_check : Warning<<br class="">+  "implicitly disabling vptr sanitizer because null checking wasn't<br class="">enabled">,<br class="">+  InGroup<AutoDisableVptrSanitizer>;<br class="">def warn_drv_object_size_disabled_O0 : Warning<<br class="">  "the object size sanitizer has no effect at -O0, but is explicitly<br class="">enabled: %0">,<br class="">  InGroup<InvalidCommandLineArgument>;<br class=""><br class="">Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=309007&r1=309006&r2=309007&view=diff<br class=""><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)<br class="">+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Jul 25 12:34:23<br class="">2017<br class="">@@ -27,6 +27,7 @@ def GNUAnonymousStruct : DiagGroup<"gnu-<br class="">def GNUAutoType : DiagGroup<"gnu-auto-type">;<br class="">def ArrayBounds : DiagGroup<"array-bounds">;<br class="">def ArrayBoundsPointerArithmetic :<br class="">DiagGroup<"array-bounds-pointer-arithmetic">;<br class="">+def AutoDisableVptrSanitizer : DiagGroup<"auto-disable-vptr-sanitizer">;<br class="">def Availability : DiagGroup<"availability">;<br class="">def Section : DiagGroup<"section">;<br class="">def AutoImport : DiagGroup<"auto-import">;<br class=""><br class="">Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=309007&r1=309006&r2=309007&view=diff<br class=""><br class="">==============================================================================<br class="">--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)<br class="">+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Jul 25 12:34:23 2017<br class="">@@ -604,20 +604,23 @@ void CodeGenFunction::EmitTypeCheck(Type<br class="">  auto PtrToAlloca =<br class=""><br class="">dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCastsNoFollowAliases());<br class=""><br class="">+  llvm::Value *IsNonNull = nullptr;<br class="">+  bool IsGuaranteedNonNull =<br class="">+      SkippedChecks.has(SanitizerKind::Null) || PtrToAlloca;<br class="">  bool AllowNullPointers = TCK == TCK_DowncastPointer || TCK ==<br class="">TCK_Upcast ||<br class="">                           TCK == TCK_UpcastToVirtualBase;<br class="">  if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&<br class="">-      !SkippedChecks.has(SanitizerKind::Null) && !PtrToAlloca) {<br class="">+      !IsGuaranteedNonNull) {<br class="">    // The glvalue must not be an empty glvalue.<br class="">-    llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr);<br class="">+    IsNonNull = Builder.CreateIsNotNull(Ptr);<br class=""><br class="">    // The IR builder can constant-fold the null check if the pointer<br class="">points to<br class="">    // a constant.<br class="">-    bool PtrIsNonNull =<br class="">+    IsGuaranteedNonNull =<br class="">        IsNonNull == llvm::ConstantInt::getTrue(getLLVMContext());<br class=""><br class="">    // Skip the null check if the pointer is known to be non-null.<br class="">-    if (!PtrIsNonNull) {<br class="">+    if (!IsGuaranteedNonNull) {<br class="">      if (AllowNullPointers) {<br class="">        // When performing pointer casts, it's OK if the value is null.<br class="">        // Skip the remaining checks in that case.<br class="">@@ -691,12 +694,24 @@ void CodeGenFunction::EmitTypeCheck(Type<br class="">  //    -- the [pointer or glvalue] is used to access a non-static data<br class="">member<br class="">  //       or call a non-static member function<br class="">  CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();<br class="">+  bool HasNullCheck = IsGuaranteedNonNull || IsNonNull;<br class="">  if (SanOpts.has(SanitizerKind::Vptr) &&<br class="">-      !SkippedChecks.has(SanitizerKind::Vptr) &&<br class="">+      !SkippedChecks.has(SanitizerKind::Vptr) && HasNullCheck &&<br class="">      (TCK == TCK_MemberAccess || TCK == TCK_MemberCall ||<br class="">       TCK == TCK_DowncastPointer || TCK == TCK_DowncastReference ||<br class="">       TCK == TCK_UpcastToVirtualBase) &&<br class="">      RD && RD->hasDefinition() && RD->isDynamicClass()) {<br class="">+    // Ensure that the pointer is non-null before loading it. If there is<br class="">no<br class="">+    // compile-time guarantee, reuse the run-time null check.<br class="">+    if (!IsGuaranteedNonNull) {<br class="">+      assert(IsNonNull && "Missing run-time null check");<br class="">+      if (!Done)<br class="">+        Done = createBasicBlock("vptr.null");<br class="">+      llvm::BasicBlock *VptrNotNull = createBasicBlock("vptr.not.null");<br class="">+      Builder.CreateCondBr(IsNonNull, VptrNotNull, Done);<br class="">+      EmitBlock(VptrNotNull);<br class="">+    }<br class="">+<br class="">    // Compute a hash of the mangled name of the type.<br class="">    //<br class="">    // FIXME: This is not guaranteed to be deterministic! Move to a<br class=""><br class="">Modified: cfe/trunk/lib/Driver/SanitizerArgs.cpp<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/SanitizerArgs.cpp?rev=309007&r1=309006&r2=309007&view=diff<br class=""><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Driver/SanitizerArgs.cpp (original)<br class="">+++ cfe/trunk/lib/Driver/SanitizerArgs.cpp Tue Jul 25 12:34:23 2017<br class="">@@ -306,6 +306,13 @@ SanitizerArgs::SanitizerArgs(const ToolC<br class="">    Kinds &= ~Vptr;<br class="">  }<br class=""><br class="">+  // Disable -fsanitize=vptr if -fsanitize=null is not enabled (the vptr<br class="">+  // instrumentation is broken without run-time null checks).<br class="">+  if ((Kinds & Vptr) && !(Kinds & Null)) {<br class="">+    Kinds &= ~Vptr;<br class="">+    D.Diag(diag::warn_drv_disabling_vptr_no_null_check);<br class="">+  }<br class="">+<br class="">  // Check that LTO is enabled if we need it.<br class="">  if ((Kinds & NeedsLTO) && !D.isUsingLTO()) {<br class="">    D.Diag(diag::err_drv_argument_only_allowed_with)<br class=""><br class="">Modified: cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=309007&r1=309006&r2=309007&view=diff<br class=""><br class="">==============================================================================<br class="">--- cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp (original)<br class="">+++ cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp Tue Jul 25 12:34:23<br class="">2017<br class="">@@ -1,6 +1,6 @@<br class="">// RUN: %clang_cc1 -std=c++11<br class="">-fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift-base,shift-exponent,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function<br class="">-fsanitize-recover=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift-base,shift-exponent,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function<br class="">-emit-llvm %s -o - -triple x86_64-linux-gnu | opt -instnamer -S | FileCheck<br class="">%s<br class="">-// RUN: %clang_cc1 -std=c++11 -fsanitize=vptr,address<br class="">-fsanitize-recover=vptr,address -emit-llvm %s -o - -triple x86_64-linux-gnu<br class="">| FileCheck %s --check-prefix=CHECK-ASAN<br class="">-// RUN: %clang_cc1 -std=c++11 -fsanitize=vptr -fsanitize-recover=vptr<br class="">-emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s<br class="">--check-prefix=DOWNCAST-NULL<br class="">+// RUN: %clang_cc1 -std=c++11 -fsanitize=null,vptr,address<br class="">-fsanitize-recover=null,vptr,address -emit-llvm %s -o - -triple<br class="">x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-ASAN<br class="">+// RUN: %clang_cc1 -std=c++11 -fsanitize=null,vptr<br class="">-fsanitize-recover=null,vptr -emit-llvm %s -o - -triple x86_64-linux-gnu |<br class="">FileCheck %s --check-prefix=DOWNCAST-NULL<br class="">// RUN: %clang_cc1 -std=c++11 -fsanitize=function -emit-llvm %s -o -<br class="">-triple x86_64-linux-gnux32 | FileCheck %s --check-prefix=CHECK-X32<br class="">// RUN: %clang_cc1 -std=c++11 -fsanitize=function -emit-llvm %s -o -<br class="">-triple i386-linux-gnu | FileCheck %s --check-prefix=CHECK-X86<br class=""><br class=""><br class="">Modified: cfe/trunk/test/CodeGenCXX/ubsan-devirtualized-calls.cpp<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ubsan-devirtualized-calls.cpp?rev=309007&r1=309006&r2=309007&view=diff<br class=""><br class="">==============================================================================<br class="">--- cfe/trunk/test/CodeGenCXX/ubsan-devirtualized-calls.cpp (original)<br class="">+++ cfe/trunk/test/CodeGenCXX/ubsan-devirtualized-calls.cpp Tue Jul 25<br class="">12:34:23 2017<br class="">@@ -1,4 +1,4 @@<br class="">-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm<br class="">-fsanitize=vptr %s -o - | FileCheck %s<br class="">+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm<br class="">-fsanitize=null,vptr %s -o - | FileCheck %s<br class=""><br class="">struct Base1 {<br class="">  virtual void f1() {}<br class="">@@ -64,6 +64,11 @@ void t4() {<br class="">  // CHECK-NEXT: call void<br class="">@__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED3]]<br class="">{{.*}}, i{{[0-9]+}} %[[P1]]<br class=""><br class="">  static_cast<Base1 *>(badp)->f1(); //< No devirt, test 'badp isa Base1'.<br class="">+  // We were able to skip the null check on the first type check because<br class="">'p'<br class="">+  // is backed by an alloca. We can't skip the second null check because<br class="">'badp'<br class="">+  // is a (bitcast (load ...)).<br class="">+  // CHECK: call void @__ubsan_handle_type_mismatch<br class="">+  //<br class="">  // CHECK: %[[BADP1:[0-9]+]] = ptrtoint %struct.Base1* {{%[0-9]+}} to<br class="">i{{[0-9]+}}, !nosanitize<br class="">  // CHECK-NEXT: call void<br class="">@__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_BASE1]]<br class="">{{.*}}, i{{[0-9]+}} %[[BADP1]]<br class="">}<br class="">@@ -76,6 +81,8 @@ void t5() {<br class="">  // CHECK-NEXT: call void<br class="">@__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_1]]<br class="">{{.*}}, i{{[0-9]+}} %[[P1]]<br class=""><br class="">  static_cast<Base1 *>(badp)->f1(); //< Devirt Base1::f1 to Derived4::f1.<br class="">+  // CHECK: call void @__ubsan_handle_type_mismatch<br class="">+  //<br class="">  // CHECK: %[[BADP1:[0-9]+]] = ptrtoint %struct.Derived4* {{%[0-9]+}} to<br class="">i{{[0-9]+}}, !nosanitize<br class="">  // CHECK-NEXT: call void<br class="">@__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_2]]<br class="">{{.*}}, i{{[0-9]+}} %[[BADP1]]<br class="">}<br class=""><br class="">Modified: cfe/trunk/test/CodeGenCXX/ubsan-type-checks.cpp<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ubsan-type-checks.cpp?rev=309007&r1=309006&r2=309007&view=diff<br class=""><br class="">==============================================================================<br class="">--- cfe/trunk/test/CodeGenCXX/ubsan-type-checks.cpp (original)<br class="">+++ cfe/trunk/test/CodeGenCXX/ubsan-type-checks.cpp Tue Jul 25 12:34:23<br class="">2017<br class="">@@ -1,6 +1,8 @@<br class="">// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o<br class="">- %s -fsanitize=alignment | FileCheck %s -check-prefixes=ALIGN,COMMON<br class="">// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o<br class="">- %s -fsanitize=null | FileCheck %s -check-prefixes=NULL,COMMON<br class="">// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o<br class="">- %s -fsanitize=object-size | FileCheck %s -check-prefixes=OBJSIZE,COMMON<br class="">+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o<br class="">- %s -fsanitize=null,vptr | FileCheck %s -check-prefixes=VPTR<br class="">+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o<br class="">- %s -fsanitize=vptr | FileCheck %s -check-prefixes=VPTR_NO_NULL<br class=""><br class="">struct A {<br class="">  // COMMON-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv<br class="">@@ -24,13 +26,55 @@ struct B {<br class="">    // NULL: icmp ne %struct.B* %{{.*}}, null, !nosanitize<br class=""><br class="">    // OBJSIZE-NOT: call i64 @llvm.objectsize<br class="">+    // OBJSIZE: ret void<br class="">  }<br class="">};<br class=""><br class="">-void force_irgen() {<br class="">+struct Animal {<br class="">+  virtual const char *speak() = 0;<br class="">+};<br class="">+<br class="">+struct Cat : Animal {<br class="">+  const char *speak() override { return "meow"; }<br class="">+};<br class="">+<br class="">+struct Dog : Animal {<br class="">+  const char *speak() override { return "woof"; }<br class="">+};<br class="">+<br class="">+// VPTR-LABEL: define void @_Z12invalid_castP3Cat<br class="">+void invalid_cast(Cat *cat = nullptr) {<br class="">+  // First, null check the pointer:<br class="">+  //<br class="">+  // VPTR: [[ICMP:%.*]] = icmp ne %struct.Dog* {{.*}}, null<br class="">+  // VPTR-NEXT: br i1 [[ICMP]]<br class="">+  // VPTR: call void @__ubsan_handle_type_mismatch<br class="">+  //<br class="">+  // Once we're done emitting the null check, reuse the check to see if<br class="">we can<br class="">+  // proceed to the vptr check:<br class="">+  //<br class="">+  // VPTR: br i1 [[ICMP]]<br class="">+  // VPTR: call void @__ubsan_handle_dynamic_type_cache_miss<br class="">+  auto *badDog = reinterpret_cast<Dog *>(cat);<br class="">+  badDog->speak();<br class="">+}<br class="">+<br class="">+// VPTR_NO_NULL-LABEL: define void @_Z13invalid_cast2v<br class="">+void invalid_cast2() {<br class="">+  // We've got a pointer to an alloca, so there's no run-time null check<br class="">needed.<br class="">+  // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch<br class="">+  // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss<br class="">+  Cat cat;<br class="">+  cat.speak();<br class="">+}<br class="">+<br class="">+int main() {<br class="">  A a;<br class="">  a.do_nothing();<br class=""><br class="">  B b;<br class="">  b.do_nothing();<br class="">+<br class="">+  invalid_cast();<br class="">+  return 0;<br class="">}<br class=""><br class="">Modified: cfe/trunk/test/CodeGenCXX/ubsan-vtable-checks.cpp<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ubsan-vtable-checks.cpp?rev=309007&r1=309006&r2=309007&view=diff<br class=""><br class="">==============================================================================<br class="">--- cfe/trunk/test/CodeGenCXX/ubsan-vtable-checks.cpp (original)<br class="">+++ cfe/trunk/test/CodeGenCXX/ubsan-vtable-checks.cpp Tue Jul 25 12:34:23<br class="">2017<br class="">@@ -1,7 +1,7 @@<br class="">// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm<br class="">-fsanitize=null %s -o - | FileCheck %s --check-prefix=CHECK<br class="">--check-prefix=CHECK-NULL --check-prefix=ITANIUM<br class="">// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm<br class="">-fsanitize=null %s -o - | FileCheck %s --check-prefix=CHECK<br class="">--check-prefix=CHECK-NULL --check-prefix=MSABI<br class="">-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm<br class="">-fsanitize=vptr %s -o - | FileCheck %s --check-prefix=CHECK<br class="">--check-prefix=CHECK-VPTR --check-prefix=ITANIUM<br class="">-// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm<br class="">-fsanitize=vptr %s -o - | FileCheck %s --check-prefix=CHECK<br class="">--check-prefix=CHECK-VPTR --check-prefix=MSABI<br class="">+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm<br class="">-fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK<br class="">--check-prefix=CHECK-VPTR --check-prefix=ITANIUM<br class="">+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm<br class="">-fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK<br class="">--check-prefix=CHECK-VPTR --check-prefix=MSABI<br class="">struct T {<br class="">  virtual ~T() {}<br class="">  virtual int v() { return 1; }<br class=""><br class="">Modified: cfe/trunk/test/Driver/fsanitize.c<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/fsanitize.c?rev=309007&r1=309006&r2=309007&view=diff<br class=""><br class="">==============================================================================<br class="">--- cfe/trunk/test/Driver/fsanitize.c (original)<br class="">+++ cfe/trunk/test/Driver/fsanitize.c Tue Jul 25 12:34:23 2017<br class="">@@ -58,6 +58,10 @@<br class="">// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fno-rtti %s<br class="">-### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-NO-RTTI<br class="">// CHECK-UNDEFINED-NO-RTTI-NOT: vptr<br class=""><br class="">+// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined<br class="">-fno-sanitize=null %s -### 2>&1 | FileCheck %s<br class="">--check-prefix=CHECK-VPTR-NO-NULL<br class="">+// RUN: %clang -target x86_64-linux-gnu -fsanitize=vptr %s -### 2>&1 |<br class="">FileCheck %s --check-prefix=CHECK-VPTR-NO-NULL<br class="">+// CHECK-VPTR-NO-NULL: warning: implicitly disabling vptr sanitizer<br class="">because null checking wasn't enabled<br class="">+<br class="">// RUN: %clang -target x86_64-linux-gnu -fsanitize=address,thread<br class="">-fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANA-SANT<br class="">// CHECK-SANA-SANT: '-fsanitize=address' not allowed with<br class="">'-fsanitize=thread'<br class=""><br class="">@@ -362,8 +366,8 @@<br class="">// RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.8<br class="">-fsanitize=vptr %s -### 2>&1 | FileCheck %s<br class="">--check-prefix=CHECK-VPTR-DARWIN-OLD<br class="">// CHECK-VPTR-DARWIN-OLD: unsupported option '-fsanitize=vptr' for target<br class="">'x86_64-apple-darwin10'<br class=""><br class="">-// RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.9<br class="">-fsanitize=alignment,vptr %s -### 2>&1 | FileCheck %s<br class="">--check-prefix=CHECK-VPTR-DARWIN-NEW<br class="">-// CHECK-VPTR-DARWIN-NEW: -fsanitize=alignment,vptr<br class="">+// RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.9<br class="">-fsanitize=alignment,null,vptr %s -### 2>&1 | FileCheck %s<br class="">--check-prefix=CHECK-VPTR-DARWIN-NEW<br class="">+// CHECK-VPTR-DARWIN-NEW: -fsanitize=alignment,null,vptr<br class=""><br class="">// RUN: %clang -target armv7-apple-ios7 -miphoneos-version-min=7.0<br class="">-fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-IOS<br class="">// CHECK-ASAN-IOS: -fsanitize=address<br class=""><br class="">Modified: cfe/trunk/test/Driver/rtti-options.cpp<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/rtti-options.cpp?rev=309007&r1=309006&r2=309007&view=diff<br class=""><br class="">==============================================================================<br class="">--- cfe/trunk/test/Driver/rtti-options.cpp (original)<br class="">+++ cfe/trunk/test/Driver/rtti-options.cpp Tue Jul 25 12:34:23 2017<br class="">@@ -16,14 +16,14 @@<br class="">// Make sure we only error/warn once, when trying to enable vptr and<br class="">// undefined and have -fno-rtti<br class="">// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=undefined<br class="">-fsanitize=vptr -fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR<br class="">-check-prefix=CHECK-OK %s<br class="">-// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=vptr %s<br class="">2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">-// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=vptr<br class="">-frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">-// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=vptr<br class="">-fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s<br class="">+// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=null,vptr<br class="">%s 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">+// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=null,vptr<br class="">-frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">+// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=null,vptr<br class="">-fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s<br class="">// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=undefined<br class="">%s 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">// RUN: %clang -### -c -target x86_64-unknown-linux -fsanitize=undefined<br class="">-frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">-// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr %s 2>&1 |<br class="">FileCheck -check-prefix=CHECK-SAN-WARN %s<br class="">-// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr -frtti %s<br class="">2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">-// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=vptr -fno-rtti<br class="">%s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s<br class="">+// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=null,vptr %s<br class="">2>&1 | FileCheck -check-prefix=CHECK-SAN-WARN %s<br class="">+// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=null,vptr<br class="">-frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class="">+// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=null,vptr<br class="">-fno-rtti %s 2>&1 | FileCheck -check-prefix=CHECK-SAN-ERROR %s<br class="">// RUN: %clang -### -c -target x86_64-scei-ps4 -fsanitize=undefined<br class="">-frtti %s 2>&1 | FileCheck -check-prefix=CHECK-OK %s<br class=""><br class="">// Exceptions + no/default rtti<br class=""><br class=""><br class="">_______________________________________________<br class="">cfe-commits mailing list<br class="">cfe-commits@lists.llvm.org<br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits<br class=""></blockquote><br class=""><br class=""><br class="">_______________________________________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits<br class=""><br class=""></blockquote></blockquote><br class="">_______________________________________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits<br class=""></div></div></blockquote></div><br class=""></div></body></html>