1 // RUN: %clangxx_cfi_dso -DSHARED_LIB -fPIC -g -fsanitize-stats -shared -o %t.so %s 2 // RUN: %clangxx_cfi_dso -g -fsanitize-stats -o %t %s %t.so 3 // RUN: env SANITIZER_STATS_PATH=%t.stats %t 4 // RUN: sanstats %t.stats | FileCheck %s 5 6 struct ABase {}; 7 8 struct A : ABase { vfA9 virtual void vf() {} nvfA10 void nvf() {} 11 }; 12 13 extern "C" void vcall(A *a); 14 extern "C" void nvcall(A *a); 15 16 #ifdef SHARED_LIB 17 vcall(A * a)18extern "C" __attribute__((noinline)) void vcall(A *a) { 19 // CHECK: stats.cpp:[[@LINE+1]] vcall cfi-vcall 37 20 a->vf(); 21 } 22 nvcall(A * a)23extern "C" __attribute__((noinline)) void nvcall(A *a) { 24 // CHECK: stats.cpp:[[@LINE+1]] nvcall cfi-nvcall 51 25 a->nvf(); 26 } 27 28 #else 29 dcast(A * a)30extern "C" __attribute__((noinline)) A *dcast(A *a) { 31 // CHECK: stats.cpp:[[@LINE+1]] dcast cfi-derived-cast 24 32 return (A *)(ABase *)a; 33 } 34 ucast(A * a)35extern "C" __attribute__((noinline)) A *ucast(A *a) { 36 // CHECK: stats.cpp:[[@LINE+1]] ucast cfi-unrelated-cast 81 37 return (A *)(char *)a; 38 } 39 unreachable(A * a)40extern "C" __attribute__((noinline)) void unreachable(A *a) { 41 // CHECK-NOT: unreachable 42 a->vf(); 43 } 44 main()45int main() { 46 A a; 47 for (unsigned i = 0; i != 37; ++i) 48 vcall(&a); 49 for (unsigned i = 0; i != 51; ++i) 50 nvcall(&a); 51 for (unsigned i = 0; i != 24; ++i) 52 dcast(&a); 53 for (unsigned i = 0; i != 81; ++i) 54 ucast(&a); 55 for (unsigned i = 0; i != 0; ++i) 56 unreachable(&a); 57 } 58 59 #endif 60