This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

c++ code that egcs kills ...


The following code demonstrates a bug in how egcs handles c++. 

Has this been seen before? Is there hope of fixing it in a future version?
We are stuck, because RedHat Linux uses egcs, so we can't get any of our
code to work.

-----------

The following code demonstrates a bug in egcs 1.0.3. 

  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
B::foo  0xbffffb18
C::foo  0xbffffb20
D::foo  0xbffffb18
E::foo  0xbffffb18
object constructed
E::foo  0xbffffb18
test finished

egcs 1.0.3 produces the incorrect output indicated below: 

starting test
A::foo  0xbffffb40
B::foo  0xbffffb38
C::foo  0xbffffb38
D::foo  0xbffffb2c	<------ incorrect
E::foo  0xbffffb28
object constructed
E::foo  0xbffffb28
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
output of D::foo() and E::foo() by exactly the same amount.

Also note that B::foo() and C::foo() should probably not be printing the same result. (They don't with g++ 2.7.2.) 

#include <iostream.h>

class A
{
public:

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

private:

        int a;
};

class B : virtual public A
{
public:

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

private:

        int b;
};

class C : virtual public A
{
public:

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

private:

        int c;
};

class D : public B, public C
{
public:

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

private:

        int d;
};

class E : public D
{
public:

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

private:

        int e;
};

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]