1 /* Test STT_GNU_IFUNC symbols:
2 
3    1. Direct function call.
4    2. Function pointer.
5    3. Visibility without override.
6  */
7 
8 #include <stdlib.h>
9 
10 int ret_foo;
11 int ret_foo_hidden;
12 int ret_foo_protected;
13 
14 extern int foo (void);
15 extern int foo_protected (void);
16 
17 #ifndef FOO_P
18 typedef int (*foo_p) (void);
19 #endif
20 
21 foo_p foo_ptr = foo;
22 foo_p foo_procted_ptr = foo_protected;
23 
24 extern foo_p get_foo_p (void);
25 extern foo_p get_foo_hidden_p (void);
26 extern foo_p get_foo_protected_p (void);
27 
28 int
main(void)29 main (void)
30 {
31   foo_p p;
32 
33   if (foo_ptr != foo)
34     abort ();
35   if (foo () != -1)
36     abort ();
37   if ((*foo_ptr) () != -1)
38     abort ();
39 
40   if (foo_procted_ptr != foo_protected)
41     abort ();
42   if (foo_protected () != 0)
43     abort ();
44   if ((*foo_procted_ptr) () != 0)
45     abort ();
46 
47   p = get_foo_p ();
48   if (p != foo)
49     abort ();
50   if (ret_foo != -1 || (*p) () != ret_foo)
51     abort ();
52 
53   p = get_foo_hidden_p ();
54   if (ret_foo_hidden != 1 || (*p) () != ret_foo_hidden)
55     abort ();
56 
57   p = get_foo_protected_p ();
58   if (p != foo_protected)
59     abort ();
60   if (ret_foo_protected != 0 || (*p) () != ret_foo_protected)
61     abort ();
62 
63   return 0;
64 }
65