1 // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment | FileCheck %s -check-prefixes=ALIGN,COMMON 2 // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null | FileCheck %s -check-prefixes=NULL,COMMON 3 // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=object-size | FileCheck %s -check-prefixes=OBJSIZE,COMMON 4 // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null,vptr | FileCheck %s -check-prefixes=VPTR 5 // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=vptr | FileCheck %s -check-prefixes=VPTR_NO_NULL 6 7 struct A { 8 // COMMON-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv 9 void do_nothing() { 10 // ALIGN-NOT: ptrtoint %struct.A* %{{.*}} to i64, !nosanitize 11 12 // NULL: icmp ne %struct.A* %{{.*}}, null, !nosanitize 13 14 // OBJSIZE-NOT: call i64 @llvm.objectsize 15 } 16 }; 17 18 struct B { 19 int x; 20 21 // COMMON-LABEL: define linkonce_odr void @_ZN1B10do_nothingEv 22 void do_nothing() { 23 // ALIGN: ptrtoint %struct.B* %{{.*}} to i64, !nosanitize 24 // ALIGN: and i64 %{{.*}}, 3, !nosanitize 25 26 // NULL: icmp ne %struct.B* %{{.*}}, null, !nosanitize 27 28 // OBJSIZE-NOT: call i64 @llvm.objectsize 29 // OBJSIZE: ret void 30 } 31 }; 32 33 struct Animal { 34 virtual const char *speak() = 0; 35 }; 36 37 struct Cat : Animal { 38 const char *speak() override { return "meow"; } 39 }; 40 41 struct Dog : Animal { 42 const char *speak() override { return "woof"; } 43 }; 44 45 // VPTR-LABEL: define{{.*}} void @_Z12invalid_castP3Cat 46 void invalid_cast(Cat *cat = nullptr) { 47 // If -fsanitize=null is available, we'll reuse its check: 48 // 49 // VPTR: [[ICMP:%.*]] = icmp ne %struct.Dog* {{.*}}, null 50 // VPTR-NEXT: br i1 [[ICMP]] 51 // VPTR: call void @__ubsan_handle_type_mismatch 52 // VPTR-NOT: icmp ne %struct.Dog* {{.*}}, null 53 // VPTR: br i1 [[ICMP]] 54 // VPTR: call void @__ubsan_handle_dynamic_type_cache_miss 55 // 56 // Fall back to the vptr sanitizer's null check when -fsanitize=null isn't 57 // available. 58 // 59 // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch 60 // VPTR_NO_NULL: [[ICMP:%.*]] = icmp ne %struct.Dog* {{.*}}, null 61 // VPTR_NO_NULL-NEXT: br i1 [[ICMP]] 62 // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss 63 auto *badDog = reinterpret_cast<Dog *>(cat); 64 badDog->speak(); 65 } 66 67 // VPTR_NO_NULL-LABEL: define{{.*}} void @_Z13invalid_cast2v 68 void invalid_cast2() { 69 // We've got a pointer to an alloca, so there's no run-time null check needed. 70 // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch 71 // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss 72 Cat cat; 73 cat.speak(); 74 } 75 76 int main() { 77 A a; 78 a.do_nothing(); 79 80 B b; 81 b.do_nothing(); 82 83 invalid_cast(); 84 return 0; 85 } 86