1// { dg-do run  }
2// prms-id: 3708
3
4extern "C" int printf (const char *, ...);
5extern "C" int atoi (const char *);
6
7void *ptr;
8
9class A {
10public:
11  A() { printf ("A is constructed.\n"); }
12  virtual void xx(int doit) { printf ("A is destructed.\n"); }
13};
14
15class A1 {
16public:
17  A1() { printf ("A1 is constructed.\n"); }
18  virtual void xx(int doit) { printf ("A1 is destructed.\n"); }
19};
20
21class B :  public A1, public virtual A {
22public:
23  B() { printf ("B is constructed.\n"); }
24  virtual void xx(int doit) {
25    printf ("B is destructed.\n");
26    A1::xx (1);
27    if (doit) A::xx (1);
28  }
29};
30
31int num;
32
33class C : public virtual A, public B {
34public:
35  C() { ++num; printf ("C is constructed.\n");
36      ptr = this;
37      }
38  virtual void xx(int doit) {
39    --num;
40    if (ptr != this)
41      printf("FAIL\n%x != %x\n", ptr, this);
42    printf ("C is destructed.\n");
43    B::xx (0);
44    if (doit) A::xx (1);
45  }
46};
47
48void fooA(A *a) {
49  printf ("Casting to A!\n");
50  a->xx (1);
51}
52void fooA1(A1 *a) {
53  printf ("Casting to A1!\n");
54  a->xx (1);
55}
56
57void fooB(B *b) {
58  printf ("Casting to B!\n");
59  b->xx (1);
60}
61
62void fooC(C *c) {
63  printf ("Casting to C!\n");
64  c->xx (1);
65}
66
67int main(int argc, char *argv[]) {
68  printf ("*** Construct C object!\n");
69  C *c = new C();
70
71  int i = 0;
72
73  printf ("*** Try to delete the casting pointer!\n");
74  switch (i)
75    {
76    case 0: fooA1(c);
77      break;
78    case 1: fooA(c);
79      break;
80    case 2: fooB(c);
81      break;
82    case 3: fooC(c);
83      break;
84    }
85
86  return num!=0;
87}
88