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 // CFI-icall is not implemented in thinlto mode => ".cfi" suffixes are missing 7 // in sanstats output. 8 9 struct ABase {}; 10 11 struct A : ABase { 12 virtual void vf() {} 13 void nvf() {} 14 }; 15 16 extern "C" void vcall(A *a); 17 extern "C" void nvcall(A *a); 18 19 #ifdef SHARED_LIB 20 21 extern "C" __attribute__((noinline)) void vcall(A *a) { 22 // CHECK: stats.cpp:[[@LINE+1]] vcall.cfi cfi-vcall 37 23 a->vf(); 24 } 25 26 extern "C" __attribute__((noinline)) void nvcall(A *a) { 27 // CHECK: stats.cpp:[[@LINE+1]] nvcall.cfi cfi-nvcall 51 28 a->nvf(); 29 } 30 31 #else 32 33 extern "C" __attribute__((noinline)) A *dcast(A *a) { 34 // CHECK: stats.cpp:[[@LINE+1]] dcast.cfi cfi-derived-cast 24 35 return (A *)(ABase *)a; 36 } 37 38 extern "C" __attribute__((noinline)) A *ucast(A *a) { 39 // CHECK: stats.cpp:[[@LINE+1]] ucast.cfi cfi-unrelated-cast 81 40 return (A *)(char *)a; 41 } 42 43 extern "C" __attribute__((noinline)) void unreachable(A *a) { 44 // CHECK-NOT: unreachable 45 a->vf(); 46 } 47 48 int main() { 49 A a; 50 for (unsigned i = 0; i != 37; ++i) 51 vcall(&a); 52 for (unsigned i = 0; i != 51; ++i) 53 nvcall(&a); 54 for (unsigned i = 0; i != 24; ++i) 55 dcast(&a); 56 for (unsigned i = 0; i != 81; ++i) 57 ucast(&a); 58 for (unsigned i = 0; i != 0; ++i) 59 unreachable(&a); 60 } 61 62 #endif 63