1 /* PR ipa/81128 */
2 /* { dg-do run } */
3 /* { dg-options "-O3" } */
4 /* { dg-require-ifunc "" } */
5 
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <time.h>
10 
11 int resolver_fn = 0;
12 int resolved_fn = 0;
13 
14 static inline void
do_it_right_at_runtime_A()15 do_it_right_at_runtime_A ()
16 {
17   resolved_fn++;
18 }
19 
20 static inline void
do_it_right_at_runtime_B()21 do_it_right_at_runtime_B ()
22 {
23   resolved_fn++;
24 }
25 
26 static inline void do_it_right_at_runtime (void);
27 
28 void do_it_right_at_runtime (void)
29   __attribute__ ((ifunc ("resolve_do_it_right_at_runtime")));
30 
resolve_do_it_right_at_runtime(void)31 static void (*resolve_do_it_right_at_runtime (void)) (void)
32 {
33   srand (time (NULL));
34   int r = rand ();
35   resolver_fn++;
36 
37   /* Use intermediate variable to get a warning for non-matching
38    * prototype. */
39   typeof(do_it_right_at_runtime) *func;
40   if (r & 1)
41     func = do_it_right_at_runtime_A;
42   else
43     func = do_it_right_at_runtime_B;
44 
45   return (void *) func;
46 }
47 
48 int
main(void)49 main (void)
50 {
51   const unsigned int ITERS = 10;
52 
53   for (int i = ITERS; i > 0; i--)
54     {
55       do_it_right_at_runtime ();
56     }
57 
58   if (resolver_fn != 1)
59     __builtin_abort ();
60 
61   if (resolved_fn != 10)
62     __builtin_abort ();
63 
64   return 0;
65 }
66