1// { dg-do run }
2// { dg-options "-O3" }
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 A * foo (int p) = 0;
25};
26
27struct B;
28static B * __attribute__ ((noinline, noclone)) get_a_B ();
29
30struct B : public Distraction, A
31{
32  B () : Distraction(), A() { }
33  B (int pi) : Distraction (), A (pi) {}
34  virtual B * foo (int p)
35  {
36    int o = fi;
37    for (int i = 0; i < p; i++)
38      o += i + i * i;
39    go = o;
40
41    return get_a_B ();
42  }
43};
44
45
46struct B gb1 (1111), gb2 (2);
47static B * __attribute__ ((noinline, noclone))
48get_a_B ()
49{
50  return &gb1;
51}
52
53static A * __attribute__ ((noinline, noclone))
54get_an_A ()
55{
56  return &gb2;
57}
58
59}
60
61static int __attribute__ ((noinline, noclone))
62get_a_number ()
63{
64  return 5;
65}
66
67extern "C" void abort (void);
68
69int main (int argc, char *argv[])
70{
71  for (int i = 0; i < get_a_number (); i++)
72    {
73      struct A *p = get_an_A ();
74      struct A *r = p->foo (4);
75      if (r->fi != 1111)
76	abort ();
77      if (go != 22)
78	abort ();
79    }
80  return 0;
81}
82