1*673dc3d4SNico Weber // Test -fsanitize-coverage=edge,indirect-call,trace-pc
2*673dc3d4SNico Weber // RUN: %clangxx_asan -O0 -DTRACE_RT %s -o %t-rt.o -c
3*673dc3d4SNico Weber // RUN: %clangxx_asan -O0 -fsanitize-coverage=edge,trace-pc,indirect-calls %s -o %t %t-rt.o
4*673dc3d4SNico Weber // RUN: %run %t
5*673dc3d4SNico Weber #ifdef TRACE_RT
6*673dc3d4SNico Weber int pc_count;
7*673dc3d4SNico Weber void *last_callee;
__sanitizer_cov_trace_pc()8*673dc3d4SNico Weber extern "C" void __sanitizer_cov_trace_pc() {
9*673dc3d4SNico Weber   pc_count++;
10*673dc3d4SNico Weber }
__sanitizer_cov_trace_pc_indir(void * callee)11*673dc3d4SNico Weber extern "C" void __sanitizer_cov_trace_pc_indir(void *callee) {
12*673dc3d4SNico Weber   last_callee = callee;
13*673dc3d4SNico Weber }
14*673dc3d4SNico Weber #else
15*673dc3d4SNico Weber #include <stdio.h>
16*673dc3d4SNico Weber #include <assert.h>
17*673dc3d4SNico Weber extern int pc_count;
18*673dc3d4SNico Weber extern void *last_callee;
19*673dc3d4SNico Weber 
foo()20*673dc3d4SNico Weber __attribute__((noinline)) void foo() { printf("foo\n"); }
bar()21*673dc3d4SNico Weber __attribute__((noinline)) void bar() { printf("bar\n"); }
22*673dc3d4SNico Weber 
main(int argc,char ** argv)23*673dc3d4SNico Weber int main(int argc, char **argv) {
24*673dc3d4SNico Weber   void (*f)(void) = argc ? foo : bar;
25*673dc3d4SNico Weber   int c1 = pc_count;
26*673dc3d4SNico Weber   f();
27*673dc3d4SNico Weber   int c2 = pc_count;
28*673dc3d4SNico Weber   assert(c1 < c2);
29*673dc3d4SNico Weber   assert(last_callee == foo);
30*673dc3d4SNico Weber }
31*673dc3d4SNico Weber #endif
32