diff options
Diffstat (limited to 'test/cfi/cross-dso/stats.cpp')
-rw-r--r-- | test/cfi/cross-dso/stats.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/test/cfi/cross-dso/stats.cpp b/test/cfi/cross-dso/stats.cpp new file mode 100644 index 000000000000..3d25d7730c77 --- /dev/null +++ b/test/cfi/cross-dso/stats.cpp @@ -0,0 +1,59 @@ +// RUN: %clangxx_cfi_dso -DSHARED_LIB -fPIC -g -fsanitize-stats -shared -o %t.so %s +// RUN: %clangxx_cfi_dso -g -fsanitize-stats -o %t %s %t.so +// RUN: env SANITIZER_STATS_PATH=%t.stats %t +// RUN: sanstats %t.stats | FileCheck %s + +struct ABase {}; + +struct A : ABase { + virtual void vf() {} + void nvf() {} +}; + +extern "C" void vcall(A *a); +extern "C" void nvcall(A *a); + +#ifdef SHARED_LIB + +extern "C" __attribute__((noinline)) void vcall(A *a) { + // CHECK: stats.cpp:[[@LINE+1]] vcall cfi-vcall 37 + a->vf(); +} + +extern "C" __attribute__((noinline)) void nvcall(A *a) { + // CHECK: stats.cpp:[[@LINE+1]] nvcall cfi-nvcall 51 + a->nvf(); +} + +#else + +extern "C" __attribute__((noinline)) A *dcast(A *a) { + // CHECK: stats.cpp:[[@LINE+1]] dcast cfi-derived-cast 24 + return (A *)(ABase *)a; +} + +extern "C" __attribute__((noinline)) A *ucast(A *a) { + // CHECK: stats.cpp:[[@LINE+1]] ucast cfi-unrelated-cast 81 + return (A *)(char *)a; +} + +extern "C" __attribute__((noinline)) void unreachable(A *a) { + // CHECK-NOT: unreachable + a->vf(); +} + +int main() { + A a; + for (unsigned i = 0; i != 37; ++i) + vcall(&a); + for (unsigned i = 0; i != 51; ++i) + nvcall(&a); + for (unsigned i = 0; i != 24; ++i) + dcast(&a); + for (unsigned i = 0; i != 81; ++i) + ucast(&a); + for (unsigned i = 0; i != 0; ++i) + unreachable(&a); +} + +#endif |