1 // { dg-do run  }
2 // Copyright (C) 2000 Free Software Foundation, Inc.
3 // Contributed by Nathan Sidwell 16 Jan 2001 <nathan@codesourcery.com>
4 
5 // Bug 1611. Under the new ABI, the vtable can be clobbered during dtoring our
6 // primary vbase. We mustn't use the vtable after that to locate our vbases.
7 
8 #if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
9 #include <stdio.h>
10 #include <stdlib.h>
11 
12 int *ctorVBase = 0;
13 int *dtorVBase = 0;
14 int *ctorVDerived = 0;
15 int *dtorVDerived = 0;
16 int *ctorB = 0;
17 int *dtorB = 0;
18 
19 struct VBase
20 {
21   int member;
VBaseVBase22   VBase ()
23     {
24       if (ctorVBase) exit (1);
25       ctorVBase = &member;
26     }
~VBaseVBase27   virtual ~VBase ()
28     {
29       if (dtorVBase) exit (2);
30       dtorVBase = &member;
31       if (dtorVBase != ctorVBase) exit (3);
32     }
OffsetVBase33   void Offset () const
34   {
35     printf ("VBase\n");
36     printf ("  VBase::member %d\n", &this->VBase::member - (int *)this);
37   }
38 };
39 
40 struct VDerived : virtual VBase
41 {
42   int member;
43 
VDerivedVDerived44   VDerived ()
45     {
46       if (ctorVDerived) exit (4);
47       ctorVDerived = &member;
48     }
~VDerivedVDerived49   virtual ~VDerived ()
50     {
51       if (dtorVDerived) exit (5);
52       dtorVDerived = &member;
53       if (dtorVDerived != ctorVDerived) exit (6);
54     }
OffsetVDerived55   void Offset () const
56   {
57     printf ("VDerived\n");
58     printf ("  VBase::member %d\n", &this->VBase::member - (int *)this);
59     printf ("  VDerived::member %d\n", &this->VDerived::member - (int *)this);
60   }
61 };
62 struct B : virtual VBase
63 {
64   int member;
OffsetB65   void Offset () const
66   {
67     printf ("B\n");
68     printf ("  VBase::member %d\n", &this->VBase::member - (int *)this);
69     printf ("  B::member %d\n", &this->B::member - (int *)this);
70   }
71 };
72 struct MostDerived : B, virtual VDerived
73 {
74   int member;
OffsetMostDerived75   void Offset () const
76   {
77     printf ("MostDerived\n");
78     printf ("  VBase::member %d\n", &this->VBase::member - (int *)this);
79     printf ("  B::member %d\n", &this->B::member - (int *)this);
80     printf ("  VDerived::member %d\n", &this->VDerived::member - (int *)this);
81     printf ("  MostDerived::member %d\n", &this->MostDerived::member - (int *)this);
82   }
83 };
84 
85 
main()86 int main ()
87 {
88   {
89     MostDerived dum;
90 
91     int *this_ = (int *)&dum;
92 
93     if (ctorVBase != &dum.VBase::member)
94       return 23;
95     if (ctorVDerived != &dum.VDerived::member)
96       return 24;
97 
98     printf ("  VBase::member %d\n", &dum.VBase::member - this_);
99     printf ("  B::member %d\n", &dum.B::member - this_);
100     printf ("  VDerived::member %d\n", &dum.VDerived::member - this_);
101     printf ("  MostDerived::member %d\n", &dum.MostDerived::member - this_);
102     dum.MostDerived::Offset ();
103     dum.B::Offset ();
104     dum.VDerived::Offset ();
105     dum.VBase::Offset ();
106   }
107   return 0;
108 }
109 #else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
110 
main()111 int main ()
112 {
113 }
114 
115 #endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
116