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