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 // FIXME: We currently emit the wrong debug info under devirtualization.
6 // UNSUPPORTED: devirt
7 
8 struct ABase {};
9 
10 struct A : ABase {
vfA11   virtual void vf() {}
nvfA12   void nvf() {}
13 };
14 
vcall(A * a)15 extern "C" __attribute__((noinline)) void vcall(A *a) {
16   // CHECK: stats.cpp:[[@LINE+1]] {{_?}}vcall cfi-vcall 37
17   a->vf();
18 }
19 
nvcall(A * a)20 extern "C" __attribute__((noinline)) void nvcall(A *a) {
21   // CHECK: stats.cpp:[[@LINE+1]] {{_?}}nvcall cfi-nvcall 51
22   a->nvf();
23 }
24 
dcast(A * a)25 extern "C" __attribute__((noinline)) A *dcast(A *a) {
26   // CHECK: stats.cpp:[[@LINE+1]] {{_?}}dcast cfi-derived-cast 24
27   return (A *)(ABase *)a;
28 }
29 
ucast(A * a)30 extern "C" __attribute__((noinline)) A *ucast(A *a) {
31   // CHECK: stats.cpp:[[@LINE+1]] {{_?}}ucast cfi-unrelated-cast 81
32   return (A *)(char *)a;
33 }
34 
unreachable(A * a)35 extern "C" __attribute__((noinline)) void unreachable(A *a) {
36   // CHECK-NOT: unreachable
37   a->vf();
38 }
39 
main()40 int main() {
41   A a;
42   for (unsigned i = 0; i != 37; ++i)
43     vcall(&a);
44   for (unsigned i = 0; i != 51; ++i)
45     nvcall(&a);
46   for (unsigned i = 0; i != 24; ++i)
47     dcast(&a);
48   for (unsigned i = 0; i != 81; ++i)
49     ucast(&a);
50   for (unsigned i = 0; i != 0; ++i)
51     unreachable(&a);
52 }
53