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