111
|
1 /* { dg-do run } */
|
|
2 /* { dg-require-ifunc "" } */
|
|
3 /* { dg-options "-Wno-pmf-conversions" } */
|
|
4
|
|
5 struct Klass
|
|
6 {
|
|
7 int a[4];
|
|
8
|
|
9 int implementation ();
|
|
10 int magic ();
|
|
11
|
|
12 /* An ifunc resolver must return a pointer to an ordinary (non-member)
|
|
13 function. To make it possible to use ifunc with member functions,
|
|
14 the resolver must convert a member function pointer to an ordinary
|
|
15 function pointer (slicing off the high word). */
|
|
16 typedef int Func (Klass*);
|
|
17
|
|
18 static Func* resolver ();
|
|
19 };
|
|
20
|
|
21 int Klass::implementation ()
|
|
22 {
|
|
23 __builtin_printf ("'ere I am JH\n");
|
|
24 return a[0] + a[1] + a[2] + a[3];
|
|
25 }
|
|
26
|
|
27 Klass::Func* Klass::resolver (void)
|
|
28 {
|
|
29 /* GCC guarantees this conversion to be safe and the resulting pointer
|
|
30 usable to call the member function using ordinary (i.e., non-member)
|
|
31 function call syntax. */
|
|
32
|
|
33 return reinterpret_cast<Func*>(&Klass::implementation);
|
|
34 }
|
|
35
|
|
36 int f (void) __attribute__ ((ifunc ("foo")));
|
|
37
|
|
38 typedef int (F)(void);
|
|
39 extern "C" F* foo () { return 0; }
|
|
40
|
|
41
|
|
42 int Klass::magic () __attribute__ ((ifunc ("_ZN5Klass8resolverEv")));
|
|
43
|
|
44 int main ()
|
|
45 {
|
|
46 Klass obj;
|
|
47
|
|
48 obj.a[0] = 1;
|
|
49 obj.a[1] = 2;
|
|
50 obj.a[2] = 3;
|
|
51 obj.a[3] = 4;
|
|
52
|
|
53 return !(obj.magic () == 10);
|
|
54 }
|