Logo Search packages:      
Sourcecode: gcc-2.95 version File versions

bug-34876.cc

/*
Package: g++
Version: 2.91.63-1.1

Please see the following URL for details on the problem and a possible
fix:

http://www.cygnus.com/ml/egcs-bugs/1998-Aug/0409.html

Below is code which demonstrates the bug (provided by John Lindal
<jafl@alice.wonderland.caltech.edu>) when vtable thunks are turned on:

  B
 / \
A   D - E
 \ /
  C

In the above inheritance tree, B and C inherit virtually from A. When an
object of type E is constructed, D's constructor calls a function in A
which in turn calls a
virtual function overridden by D. This requires a downcast from type A
to type D, and egcs incorrectly adjusts the object pointer, forgetting
the size of E's member data.

The correct output, produced by g++ 2.7.2, is:

starting test
A::foo  0xbffffb30 1
B::foo  0xbffffb18 1
C::foo  0xbffffb20 1
D::foo  0xbffffb18 1
E::foo  0xbffffb18 1
object constructed
E::foo  0xbffffb18 1
test finished

egcs 1.0.3 and 1.1.0 produce the incorrect output shown in bold:

starting test
A::foo  0xbffffb40 1
B::foo  0xbffffb38 1073783288
C::foo  0xbffffb38 1073783288
D::foo  0xbffffb2c 1073783288
E::foo  0xbffffb28 1
object constructed
E::foo  0xbffffb28 1
test finished

The minimal source code required to reproduce the problem is listed
below. Changing the size of E's member data changes the difference
between the pointer printed by
D::foo() and E::foo() by exactly the same amount.

-----------------------------
*/

#include <iostream.h>

class A
{
public:

        A() { a=1; bar(); };
        virtual void foo() {
                cout << "A::foo  " << this << ' ' << a << endl; };
        void bar() { foo(); };

private:

        int a;
};

class B : virtual public A
{
public:

        B() { b=1; bar(); };
        virtual void foo() {
                cout << "B::foo  " << this << ' ' << b << endl; };

private:

        int b;
};

class C : virtual public A
{
public:

        C() { c=1; bar(); };
        virtual void foo() {
                cout << "C::foo  " << this << ' ' << c << endl; };

private:

        int c;
};

class D : public B, public C
{
public:

        D() { d=1; bar(); };
        virtual void foo() {
                cout << "D::foo  " << this << ' ' << d << endl; };

private:

        int d;
};

class E : public D
{
public:

        E() { e=1; bar(); };
        virtual void foo() {
                cout << "E::foo  " << this << ' ' << e << endl; };

private:

        int e;
};

int
main()
{
        cout << "starting test" << endl;
        E e;
        cout << "object constructed" << endl;
        e.bar();
        cout << "test finished" << endl;
        return 0;
}

Generated by  Doxygen 1.6.0   Back to index