Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -461,7 +461,7 @@ llvm::Value *Cond = nullptr; llvm::BasicBlock *Done = nullptr; - if (SanOpts->Null) { + if (SanOpts->Null || TCK == TCK_DowncastPointer) { // The glvalue must not be an empty glvalue. Cond = Builder.CreateICmpNE( Address, llvm::Constant::getNullValue(Address->getType())); Index: test/CodeGenCXX/catch-undef-behavior.cpp =================================================================== --- test/CodeGenCXX/catch-undef-behavior.cpp +++ test/CodeGenCXX/catch-undef-behavior.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -fsanitize=vptr -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=DOWNCAST-NULL struct S { double d; @@ -182,10 +183,15 @@ } // CHECK: @_Z20bad_downcast_pointer +// DOWNCAST-NULL: @_Z20bad_downcast_pointer void bad_downcast_pointer(S *p) { // CHECK: %[[NONNULL:.*]] = icmp ne {{.*}}, null // CHECK: br i1 %[[NONNULL]], + // A null poiner access is guarded without -fsanitize=null. + // DOWNCAST-NULL: %[[NONNULL:.*]] = icmp ne {{.*}}, null + // DOWNCAST-NULL: br i1 %[[NONNULL]], + // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8( // CHECK: %[[E1:.*]] = icmp uge i64 %[[SIZE]], 24 // CHECK: %[[MISALIGN:.*]] = and i64 %{{.*}}, 7 @@ -200,6 +206,9 @@ // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss // CHECK: br label + + // DOWNCAST-NULL: call void @__ubsan_handle_dynamic_type_cache_miss + // DOWNCAST-NULL: br label (void) static_cast(p); }