86 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment | FileCheck %s -check-prefixes=ALIGN,COMMON2// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null | FileCheck %s -check-prefixes=NULL,COMMON3// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=object-size | FileCheck %s -check-prefixes=OBJSIZE,COMMON4// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null,vptr | FileCheck %s -check-prefixes=VPTR5// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=vptr | FileCheck %s -check-prefixes=VPTR_NO_NULL6 7struct A {8 // COMMON-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv9 void do_nothing() {10 // ALIGN-NOT: ptrtoint ptr %{{.*}} to i64, !nosanitize11 12 // NULL: icmp ne ptr %{{.*}}, null, !nosanitize13 14 // OBJSIZE-NOT: call i64 @llvm.objectsize15 }16};17 18struct B {19 int x;20 21 // COMMON-LABEL: define linkonce_odr void @_ZN1B10do_nothingEv22 void do_nothing() {23 // ALIGN: ptrtoint ptr %{{.*}} to i64, !nosanitize24 // ALIGN: and i64 %{{.*}}, 3, !nosanitize25 26 // NULL: icmp ne ptr %{{.*}}, null, !nosanitize27 28 // OBJSIZE-NOT: call i64 @llvm.objectsize29 // OBJSIZE: ret void30 }31};32 33struct Animal {34 virtual const char *speak() = 0;35};36 37struct Cat : Animal {38 const char *speak() override { return "meow"; }39};40 41struct Dog : Animal {42 const char *speak() override { return "woof"; }43};44 45// VPTR-LABEL: define{{.*}} void @_Z12invalid_castP3Cat46void invalid_cast(Cat *cat = nullptr) {47 // If -fsanitize=null is available, we'll reuse its check:48 //49 // VPTR: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null50 // VPTR-NEXT: br i1 [[ICMP]]51 // VPTR: call void @__ubsan_handle_type_mismatch52 // VPTR-NOT: icmp ne ptr {{.*}}, null53 // VPTR: br i1 [[ICMP]]54 // VPTR: call void @__ubsan_handle_dynamic_type_cache_miss55 //56 // Fall back to the vptr sanitizer's null check when -fsanitize=null isn't57 // available.58 //59 // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch60 // VPTR_NO_NULL: [[ICMP:%.*]] = icmp ne ptr {{.*}}, null61 // VPTR_NO_NULL-NEXT: br i1 [[ICMP]]62 // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss63 auto *badDog = reinterpret_cast<Dog *>(cat);64 badDog->speak();65}66 67// VPTR_NO_NULL-LABEL: define{{.*}} void @_Z13invalid_cast2v68void 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_mismatch71 // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss72 Cat cat;73 cat.speak();74}75 76int 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