1 /* Verify that simple indirect calls are inlined even without early
2    inlining..  */
3 /* { dg-do run } */
4 /* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining"  } */
5 
6 extern void abort (void);
7 
8 struct S
9 {
10   int i;
11   void (*f)(struct S *);
12   int j,k,l;
13 };
14 
15 struct Z
16 {
17   unsigned u;
18   void (*f)(struct Z *, int);
19   struct Z *next;
20 };
21 
22 static struct S *gs;
23 static int gr = 111;
24 char gc[1024];
25 
26 static __attribute__ ((noinline, noclone)) struct S *
get_s(void)27 get_s (void)
28 {
29   return (struct S *) &gc;
30 }
31 
wrong_target(struct S * s)32 static void wrong_target (struct S *s)
33 {
34   abort ();
35 }
36 
good_target(struct S * s)37 static void good_target (struct S *s)
38 {
39   gr = 0;
40 }
41 
g1(struct S * s)42 static void g1 (struct S *s)
43 {
44   s->f (s);
45 }
46 
f2(struct Z * z)47 static void f2 (struct Z *z)
48 {
49   gs->f = good_target;
50   g1 ((struct S *) z);
51 }
52 
f1(struct S * s)53 static inline __attribute__ ((flatten)) void f1 (struct S *s)
54 {
55   f2 ((struct Z *) s);
56 }
57 
main(int argc,char ** argv)58 int main (int argc, char **argv)
59 {
60   struct S *s = get_s();
61   s->i = 5678;
62   s->f = wrong_target;
63   s->j = 1234;
64   gs = s;
65   f1 (s);
66 
67   return gr;
68 }
69 
70 
71 /* { dg-final { scan-ipa-dump-not "wrong_target\[^\\n\]*inline copy in" "inline"  } } */
72