1// { dg-do run }
2// { dg-options "-O3 -fdump-ipa-cp" }
3
4struct Distraction
5{
6  char fc[8];
7  virtual Distraction * return_self ()
8  { return this; }
9};
10
11namespace {
12
13struct A;
14static A * __attribute__ ((noinline, noclone)) get_an_A ();
15
16static int go;
17
18struct A
19{
20  int fi;
21
22  A () : fi(777) {}
23  A (int pi) : fi (pi) {}
24  virtual void foo (int p) = 0;
25};
26
27struct B : public Distraction, A
28{
29  B () : Distraction(), A() { }
30  B (int pi) : Distraction (), A (pi) {}
31  virtual void foo (int p)
32  {
33    int o = fi;
34    for (int i = 0; i < p; i++)
35      o += i + i * i;
36    go = o;
37  }
38};
39
40
41struct B gb (2);
42static A * __attribute__ ((noinline, noclone))
43get_an_A ()
44{
45  return &gb;
46}
47
48}
49
50static int __attribute__ ((noinline, noclone))
51get_a_number ()
52{
53  return 5;
54}
55
56extern "C" void abort (void);
57
58static void __attribute__ ((noinline, noclone))
59bar ()
60{
61  for (int i = 0; i < get_a_number (); i++)
62    {
63      struct A *p = get_an_A ();
64      p->foo (4);
65      if (go != 22)
66	abort ();
67    }
68}
69
70int main (int argc, char *argv[])
71{
72  for (int i = 0; i < get_a_number (); i++)
73    {
74      struct A *p = get_an_A ();
75      p->foo (4);
76      if (go != 22)
77	abort ();
78    }
79
80  bar ();
81  return 0;
82}
83
84/* { dg-final { scan-ipa-dump-times "Thunk fixed offset" 2 "cp"} } */
85/* { dg-final { cleanup-ipa-dump "cp" } } */
86