dynamic cast bug.
Karl Nelson
kenelson@ece.ucdavis.edu
Sat Jun 24 17:05:00 GMT 2000
Category: c++
Class: wrong-code
Version: all (2.8.1, egcs, 2.95, 2.95.2, 2.95.3 tested)
Architecture: all (Sun, HP-UX, Irix, i86 tested)
Summary:
dynamic_cast with during a constructor when the base class
uses virtual inheritance and a derived class uses multiple inheritance
yields an incorrect result.
Description:
This bug was reported as a segfualt in the gtk-- C++ library.
Further tracing lead us to believe that the error was in fact
a function of the compiler.
With certain class structures it is possible for dynamic_cast to
return an incorrect pointer during the constructor. The bug does
not occur on any non-gcc compilers but has been verified to exist
up to 2.95.3. Static cast does not display that behavior.
Following construction casting works as expected. Likely this is a
bug in the vtable.
The requirements for causing the bug to appear are lengthy. There
must be a virtual inheritence earlier in the base classes and a
derived class must have multiple inheritence. A cast must happen
to one of the base classes which then is dynamic cast back up to
another base class. Since this cast is to a fully constructed
base class this should work properly.
Example program:
The code below demostrates the error. The proper output is
to print the same pointer location 9 times. However, on
gcc the code produces
0x804a830 0x804a830 0x804a838
0x804a830 0x804a830 0x804a830
0x804a830 0x804a830 0x804a830
Thus one can see that a dynamic cast from a proper base class
resulted in an incorrect pointer. The error only occurs during
construction of B0. Gtk-- unforunately execises this bug
on many programs.
O1-5 represent structures defined in the shared library gtk--.
B0-1 combine them to expose the bug.
-------------------------------------------------------------------
#include <iostream.h>
struct O1 { int i0_; virtual ~O1() {} };
struct O2 : virtual public O1 { int i1_; virtual ~O2() {} };
struct O3 : public O2 { int i2_; O3() {} virtual ~O3() {} };
struct O4 : public O3 { int i4_; };
struct O5 { int i5_; O5(){} };
class B0 : public O4
{
public:
B0()
{
foo();
}
void foo()
{
cout
<< this << " "
<< dynamic_cast<O4*>(this) << " "
<< dynamic_cast<O4*>(static_cast<O3*>(this)) << endl;
}
int i6_;
};
class B1 : public B0, public O5
{
public:
B1() { }
int i7_;
};
int main()
{
B1 *p = new B1;
B0 *b= p;
cout
<< p << " "
<< dynamic_cast<O4*>(p) << " "
<< dynamic_cast<O4*>(static_cast<O3*>(p)) << endl;
b->foo();
return 0
}
More information about the Gcc-bugs
mailing list