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

Vedant Kumar via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 31 12:48:07 PDT 2017


> On Jul 31, 2017, at 12:30 PM, Nico Weber <thakis at chromium.org> wrote:
> 
> On Mon, Jul 31, 2017 at 1:18 PM, Vedant Kumar <vsk at apple.com <mailto:vsk at apple.com>> wrote:
> The bot should start working again with -fsanitize=vptr,null.
> 
> The warning can be improved. If we find -fno-sanitize=null in the argument list, we might say:
> implicitly disabling vptr sanitizer because "-fno-sanitize=null" was specified
> 
> Otherwise we might say:
> implicitly disabling vptr sanitizer because null checking wasn't enabled, try specifying -fsanitize=null or -fsanitize=undefined
> 
> Hm, I still don't understand. I enable vptr ubsan checking, and I don't want null checking (because chromium happens to be vptr clean and we want to keep it that way, but we're not nullptr clean due to for example v8's SMIs). How do I get yesterday's behavior back?

We can teach the -fsanitize=vptr to emit its own null check when -fsanitize=null isn't available (I'll send a patch out for this). I opted not to do this initially to because I expected the two checks to either always be enabled together, or to be mutually compatible.

vedant

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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170731/0955db44/attachment-0001.html>


More information about the cfe-commits mailing list