1 /* { dg-require-effective-target return_address } */ 2 /* { dg-options "-finstrument-functions" } */ 3 /* { dg-xfail-run-if "" { powerpc-ibm-aix* } } */ 4 5 extern void abort (void); 6 7 #define ASSERT(X) if (!(X)) abort (); 8 #define NOCHK __attribute__ ((no_instrument_function)) 9 10 int entry_calls, exit_calls; 11 void (*last_fn_entered)(); 12 void (*last_fn_exited)(); 13 14 __attribute__ ((noinline)) 15 int main () NOCHK; 16 17 __attribute__ ((noinline)) foo()18void foo () 19 { 20 ASSERT (last_fn_entered == foo); 21 } 22 23 __attribute__ ((noinline)) foo2()24static void foo2 () 25 { 26 ASSERT (entry_calls == 1 && exit_calls == 0); 27 ASSERT (last_fn_entered == foo2); 28 foo (); 29 ASSERT (entry_calls == 2 && exit_calls == 1); 30 ASSERT (last_fn_entered == foo); 31 ASSERT (last_fn_exited == foo); 32 } 33 34 __attribute__ ((noinline)) 35 void nfoo (void) NOCHK; nfoo()36void nfoo () 37 { 38 ASSERT (entry_calls == 2 && exit_calls == 2); 39 ASSERT (last_fn_entered == foo); 40 ASSERT (last_fn_exited == foo2); 41 foo (); 42 ASSERT (entry_calls == 3 && exit_calls == 3); 43 ASSERT (last_fn_entered == foo); 44 ASSERT (last_fn_exited == foo); 45 } 46 main()47int main () 48 { 49 ASSERT (entry_calls == 0 && exit_calls == 0); 50 51 foo2 (); 52 53 ASSERT (entry_calls == 2 && exit_calls == 2); 54 ASSERT (last_fn_entered == foo); 55 ASSERT (last_fn_exited == foo2); 56 57 nfoo (); 58 59 ASSERT (entry_calls == 3 && exit_calls == 3); 60 ASSERT (last_fn_entered == foo); 61 62 return 0; 63 } 64 65 void __cyg_profile_func_enter (void*, void*) NOCHK; 66 void __cyg_profile_func_exit (void*, void*) NOCHK; 67 68 __attribute__ ((noinline)) __cyg_profile_func_enter(void * fn,void * parent)69void __cyg_profile_func_enter (void *fn, void *parent) 70 { 71 entry_calls++; 72 last_fn_entered = (void (*)())fn; 73 } 74 __attribute__ ((noinline)) __cyg_profile_func_exit(void * fn,void * parent)75void __cyg_profile_func_exit (void *fn, void *parent) 76 { 77 exit_calls++; 78 last_fn_exited = (void (*)())fn; 79 } 80