summaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.old-deja/g++.mike/p3708b.C
blob: 2cccc46919ab282cdcd04c9fae47691f38cb5ab6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// { dg-do run  }
// prms-id: 3708

extern "C" int printf (const char *, ...);
extern "C" void exit(int);

void *ptr;

class A {
public:
  A() { printf ("A is constructed.\n"); }
  virtual void xx(int doit) { printf ("A is destructed.\n"); }
};

class A1 {
public:
  A1() { printf ("A1 is constructed.\n"); }
  virtual void xx(int doit) { printf ("A1 is destructed.\n"); }
};

class B : public virtual A, public A1 {
public:
  B() { printf ("B is constructed.\n"); }
  virtual void xx(int doit) {
    printf ("B is destructed.\n");
    A1::xx (1);
    if (doit) A::xx (1);
  }
};

int num;

class C : public virtual A {
public:
  C() { printf ("C is constructed.\n");
      }
  virtual void xx(int doit) {
    printf ("C is destructed.\n");
    if (doit) A::xx (1);
  }
};

class D : public C, public B {
public:
  D() { ++num; printf ("D is constructed.\n");
      ptr = this;
      }
  virtual void xx(int doit) {
    --num;
    if (ptr != this) {
      printf("FAIL\n%x != %x\n", ptr, this);
      exit(1);
    }
    printf ("D is destructed.\n");
    C::xx (0);
    B::xx (0);
  }
};

void fooA(A *a) {
  printf ("Casting to A!\n");
  a->xx (1);
}
void fooA1(A1 *a) {
  printf ("Casting to A1!\n");
  a->xx (1);
}

void fooB(B *b) {
  printf ("Casting to B!\n");
  b->xx (1);
}

void fooC(C *c) {
  printf ("Casting to C!\n");
  c->xx (1);
}

int main(int argc, char *argv[]) {
  printf ("*** Construct D object!\n");
  D *d = new D();

  printf ("*** Try to delete the casting pointer!\n");
  fooA1(d);
  return num!=0;
}