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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
// { dg-do run }
// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 16 Jan 2001 <nathan@codesourcery.com>
// Bug 1611. Under the new ABI, the vtable can be clobbered during dtoring our
// primary vbase. We mustn't use the vtable after that to locate our vbases.
#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
#include <stdio.h>
#include <stdlib.h>
int *ctorVBase = 0;
int *dtorVBase = 0;
int *ctorVDerived = 0;
int *dtorVDerived = 0;
int *ctorB = 0;
int *dtorB = 0;
struct VBase
{
int member;
VBase ()
{
if (ctorVBase) exit (1);
ctorVBase = &member;
}
virtual ~VBase ()
{
if (dtorVBase) exit (2);
dtorVBase = &member;
if (dtorVBase != ctorVBase) exit (3);
}
void Offset () const
{
printf ("VBase\n");
printf (" VBase::member %d\n", &this->VBase::member - (int *)this);
}
};
struct VDerived : virtual VBase
{
int member;
VDerived ()
{
if (ctorVDerived) exit (4);
ctorVDerived = &member;
}
virtual ~VDerived ()
{
if (dtorVDerived) exit (5);
dtorVDerived = &member;
if (dtorVDerived != ctorVDerived) exit (6);
}
void Offset () const
{
printf ("VDerived\n");
printf (" VBase::member %d\n", &this->VBase::member - (int *)this);
printf (" VDerived::member %d\n", &this->VDerived::member - (int *)this);
}
};
struct B : virtual VBase
{
int member;
void Offset () const
{
printf ("B\n");
printf (" VBase::member %d\n", &this->VBase::member - (int *)this);
printf (" B::member %d\n", &this->B::member - (int *)this);
}
};
struct MostDerived : B, virtual VDerived
{
int member;
void Offset () const
{
printf ("MostDerived\n");
printf (" VBase::member %d\n", &this->VBase::member - (int *)this);
printf (" B::member %d\n", &this->B::member - (int *)this);
printf (" VDerived::member %d\n", &this->VDerived::member - (int *)this);
printf (" MostDerived::member %d\n", &this->MostDerived::member - (int *)this);
}
};
int main ()
{
{
MostDerived dum;
int *this_ = (int *)&dum;
if (ctorVBase != &dum.VBase::member)
return 23;
if (ctorVDerived != &dum.VDerived::member)
return 24;
printf (" VBase::member %d\n", &dum.VBase::member - this_);
printf (" B::member %d\n", &dum.B::member - this_);
printf (" VDerived::member %d\n", &dum.VDerived::member - this_);
printf (" MostDerived::member %d\n", &dum.MostDerived::member - this_);
dum.MostDerived::Offset ();
dum.B::Offset ();
dum.VDerived::Offset ();
dum.VBase::Offset ();
}
return 0;
}
#else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
int main ()
{
}
#endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
|