1 /* Verify that ipa-cp correctly detects the dynamic type of an object
2    under construction when doing devirtualization.  */
3 /* { dg-do run } */
4 /* { dg-options "-O3 -fno-inline"  } */
5 
6 extern "C" void abort (void);
7 
8 class Distraction
9 {
10 public:
11   float f;
12   double d;
Distraction()13   Distraction ()
14   {
15     f = 8.3;
16     d = 10.2;
17   }
18   virtual float bar (float z);
19 };
20 
21 class A
22 {
23 public:
24   int data;
25   A();
26   virtual int foo (int i);
27 };
28 
29 class B : public Distraction, public A
30 {
31 public:
32   B();
33   virtual int foo (int i);
34 };
35 
36 class C : public B
37 {
38 public:
39   virtual int foo (int i);
40 };
41 
42 
bar(float z)43 float Distraction::bar (float z)
44 {
45   f += z;
46   return f/2;
47 }
48 
foo(int i)49 int A::foo (int i)
50 {
51   return i + 1;
52 }
53 
foo(int i)54 int B::foo (int i)
55 {
56   return i + 2;
57 }
58 
foo(int i)59 int C::foo (int i)
60 {
61   return i + 3;
62 }
63 
get_input(void)64 int __attribute__ ((noinline,noclone)) get_input(void)
65 {
66   return 1;
67 }
68 
69 static int __attribute__ ((noinline))
middleman(class A * obj,int i)70 middleman (class A *obj, int i)
71 {
72   return obj->foo (i);
73 }
74 
75 static void __attribute__ ((noinline))
sth2(A * a)76 sth2 (A *a)
77 {
78   if (a->foo (get_input ()) != 3)
79     abort ();
80 }
81 
sth1(B * b)82 inline void __attribute__ ((always_inline)) sth1 (B *b)
83 {
84   sth2 (b);
85 }
86 
A()87 inline __attribute__ ((always_inline)) A::A()
88 {
89   if (middleman (this, get_input ()) != 2)
90     abort ();
91 }
92 
B()93 B::B() : Distraction(), A()
94 {
95   sth1 (this);
96 }
97 
bah()98 static void bah ()
99 {
100   class C c;
101 }
102 
main(int argc,char * argv[])103 int main (int argc, char *argv[])
104 {
105   int i;
106 
107   for (i = 0; i < 10; i++)
108     bah ();
109   return 0;
110 }
111