1/* { dg-require-effective-target return_address } */ 2/* { dg-options "-finstrument-functions" } */ 3/* { dg-xfail-run-if "" { powerpc-ibm-aix* } "*" "" } */ 4 5extern void abort (void); 6 7#define ASSERT(X) if (!(X)) abort (); 8#define NOCHK __attribute__ ((no_instrument_function)) 9 10int entry_calls, exit_calls; 11void (*last_fn_entered)(); 12void (*last_fn_exited)(); 13 14__attribute__ ((noinline)) 15int main () NOCHK; 16 17__attribute__ ((noinline)) 18void foo () 19{ 20 ASSERT (last_fn_entered == foo); 21} 22 23__attribute__ ((noinline)) 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)) 35void nfoo (void) NOCHK; 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 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 65void __cyg_profile_func_enter (void (*fn)(), void (*parent)()) NOCHK; 66void __cyg_profile_func_exit (void (*fn)(), void (*parent)()) NOCHK; 67 68__attribute__ ((noinline)) 69void __cyg_profile_func_enter (void (*fn)(), void (*parent)()) 70{ 71 entry_calls++; 72 last_fn_entered = fn; 73} 74__attribute__ ((noinline)) 75void __cyg_profile_func_exit (void (*fn)(), void (*parent)()) 76{ 77 exit_calls++; 78 last_fn_exited = fn; 79} 80