// { dg-do run }
|
// { dg-do run }
|
// Copyright (C) 2000 Free Software Foundation, Inc.
|
// Copyright (C) 2000 Free Software Foundation, Inc.
|
// Contributed by Nathan Sidwell 16 Jan 2001
|
// Contributed by Nathan Sidwell 16 Jan 2001
|
|
|
// Bug 1611. Under the new ABI, the vtable can be clobbered during dtoring our
|
// 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.
|
// primary vbase. We mustn't use the vtable after that to locate our vbases.
|
|
|
#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
|
#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
|
#include
|
#include
|
#include
|
#include
|
|
|
int *ctorVBase = 0;
|
int *ctorVBase = 0;
|
int *dtorVBase = 0;
|
int *dtorVBase = 0;
|
int *ctorVDerived = 0;
|
int *ctorVDerived = 0;
|
int *dtorVDerived = 0;
|
int *dtorVDerived = 0;
|
int *ctorB = 0;
|
int *ctorB = 0;
|
int *dtorB = 0;
|
int *dtorB = 0;
|
|
|
struct VBase
|
struct VBase
|
{
|
{
|
int member;
|
int member;
|
VBase ()
|
VBase ()
|
{
|
{
|
if (ctorVBase) exit (1);
|
if (ctorVBase) exit (1);
|
ctorVBase = &member;
|
ctorVBase = &member;
|
}
|
}
|
virtual ~VBase ()
|
virtual ~VBase ()
|
{
|
{
|
if (dtorVBase) exit (2);
|
if (dtorVBase) exit (2);
|
dtorVBase = &member;
|
dtorVBase = &member;
|
if (dtorVBase != ctorVBase) exit (3);
|
if (dtorVBase != ctorVBase) exit (3);
|
}
|
}
|
void Offset () const
|
void Offset () const
|
{
|
{
|
printf ("VBase\n");
|
printf ("VBase\n");
|
printf (" VBase::member %d\n", &this->VBase::member - (int *)this);
|
printf (" VBase::member %d\n", &this->VBase::member - (int *)this);
|
}
|
}
|
};
|
};
|
|
|
struct VDerived : virtual VBase
|
struct VDerived : virtual VBase
|
{
|
{
|
int member;
|
int member;
|
|
|
VDerived ()
|
VDerived ()
|
{
|
{
|
if (ctorVDerived) exit (4);
|
if (ctorVDerived) exit (4);
|
ctorVDerived = &member;
|
ctorVDerived = &member;
|
}
|
}
|
virtual ~VDerived ()
|
virtual ~VDerived ()
|
{
|
{
|
if (dtorVDerived) exit (5);
|
if (dtorVDerived) exit (5);
|
dtorVDerived = &member;
|
dtorVDerived = &member;
|
if (dtorVDerived != ctorVDerived) exit (6);
|
if (dtorVDerived != ctorVDerived) exit (6);
|
}
|
}
|
void Offset () const
|
void Offset () const
|
{
|
{
|
printf ("VDerived\n");
|
printf ("VDerived\n");
|
printf (" VBase::member %d\n", &this->VBase::member - (int *)this);
|
printf (" VBase::member %d\n", &this->VBase::member - (int *)this);
|
printf (" VDerived::member %d\n", &this->VDerived::member - (int *)this);
|
printf (" VDerived::member %d\n", &this->VDerived::member - (int *)this);
|
}
|
}
|
};
|
};
|
struct B : virtual VBase
|
struct B : virtual VBase
|
{
|
{
|
int member;
|
int member;
|
void Offset () const
|
void Offset () const
|
{
|
{
|
printf ("B\n");
|
printf ("B\n");
|
printf (" VBase::member %d\n", &this->VBase::member - (int *)this);
|
printf (" VBase::member %d\n", &this->VBase::member - (int *)this);
|
printf (" B::member %d\n", &this->B::member - (int *)this);
|
printf (" B::member %d\n", &this->B::member - (int *)this);
|
}
|
}
|
};
|
};
|
struct MostDerived : B, virtual VDerived
|
struct MostDerived : B, virtual VDerived
|
{
|
{
|
int member;
|
int member;
|
void Offset () const
|
void Offset () const
|
{
|
{
|
printf ("MostDerived\n");
|
printf ("MostDerived\n");
|
printf (" VBase::member %d\n", &this->VBase::member - (int *)this);
|
printf (" VBase::member %d\n", &this->VBase::member - (int *)this);
|
printf (" B::member %d\n", &this->B::member - (int *)this);
|
printf (" B::member %d\n", &this->B::member - (int *)this);
|
printf (" VDerived::member %d\n", &this->VDerived::member - (int *)this);
|
printf (" VDerived::member %d\n", &this->VDerived::member - (int *)this);
|
printf (" MostDerived::member %d\n", &this->MostDerived::member - (int *)this);
|
printf (" MostDerived::member %d\n", &this->MostDerived::member - (int *)this);
|
}
|
}
|
};
|
};
|
|
|
|
|
int main ()
|
int main ()
|
{
|
{
|
{
|
{
|
MostDerived dum;
|
MostDerived dum;
|
|
|
int *this_ = (int *)&dum;
|
int *this_ = (int *)&dum;
|
|
|
if (ctorVBase != &dum.VBase::member)
|
if (ctorVBase != &dum.VBase::member)
|
return 23;
|
return 23;
|
if (ctorVDerived != &dum.VDerived::member)
|
if (ctorVDerived != &dum.VDerived::member)
|
return 24;
|
return 24;
|
|
|
printf (" VBase::member %d\n", &dum.VBase::member - this_);
|
printf (" VBase::member %d\n", &dum.VBase::member - this_);
|
printf (" B::member %d\n", &dum.B::member - this_);
|
printf (" B::member %d\n", &dum.B::member - this_);
|
printf (" VDerived::member %d\n", &dum.VDerived::member - this_);
|
printf (" VDerived::member %d\n", &dum.VDerived::member - this_);
|
printf (" MostDerived::member %d\n", &dum.MostDerived::member - this_);
|
printf (" MostDerived::member %d\n", &dum.MostDerived::member - this_);
|
dum.MostDerived::Offset ();
|
dum.MostDerived::Offset ();
|
dum.B::Offset ();
|
dum.B::Offset ();
|
dum.VDerived::Offset ();
|
dum.VDerived::Offset ();
|
dum.VBase::Offset ();
|
dum.VBase::Offset ();
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
#else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
|
#else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
|
|
|
int main ()
|
int main ()
|
{
|
{
|
}
|
}
|
|
|
#endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
|
#endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
|
|
|