1/* Verify that ipa-cp will not get confused by placement new constructing an
2   object within another one when looking for dynamic type change .  */
3/* { dg-do run } */
4/* { dg-require-effective-target nonpic } */
5/* { dg-options "-O3 -Wno-attributes"  } */
6
7extern "C" void abort (void);
8namespace std {
9  typedef __SIZE_TYPE__ size_t;
10}
11inline void* __attribute__ ((always_inline))
12operator new(std::size_t, void* __p) throw()
13{
14  return __p;
15}
16
17class A
18{
19public:
20  char data[256];
21  A();
22  virtual int foo (int i);
23};
24
25class B : public A
26{
27public:
28  virtual int foo (int i);
29};
30
31class C
32{
33public:
34  C();
35  virtual double foo (double i);
36};
37
38int A::foo (int i)
39{
40  return i + 1;
41}
42
43int B::foo (int i)
44{
45  return i + 2;
46}
47
48double C::foo (double i)
49{
50  return i + 3.5;
51}
52
53static int __attribute__ ((noinline)) middleman (class A *obj, int i)
54{
55  return obj->foo (i);
56}
57
58int __attribute__ ((noinline,noclone)) get_input(void)
59{
60  return 1;
61}
62
63__attribute__ ((always_inline)) C::C ()
64{
65}
66
67A::A ()
68{
69}
70
71static  __attribute__ ((noinline)) void bah ()
72{
73  class B b;
74
75  C *c = new ((void *) &b.data) C;
76
77  if (middleman (&b, get_input ()) != 3)
78    abort ();
79}
80
81int main (int argc, char *argv[])
82{
83  int i;
84
85  for (i = 0; i < 10; i++)
86    bah ();
87  return 0;
88}
89