cooper@gecrux.steinmetz.ge.com (Clark Cooper) (12/30/88)
System: GNU C++ 1.31
Hardware: Sun 3/50
OS: SunOS 3.4
Configuration: tm.h -> tm-sun3+.h
md -> m68k.md
Symptoms:
Given a derived class with no destructor of its own but whose base
class has a destructor that calls a virtual function, if an instance of the
derived class is deleted, the base class version of the virtual function is
called (incorrectly I believe) instead of the derived class version.
Source: bug.cc:
==================================================
#include <stream.h>
class base
{
int foo;
public:
base ();
~base();
virtual void vfcn();
};
base::base ()
{
foo = 2;
}
base::~base ()
{
cout << "Base destructor called.\n";
vfcn();
}
void base::vfcn()
{
cout << "This (base virtual fcn) shouldn't be called.\n";
}
class derived : public base
{
int bar;
public:
derived() { bar = 7;}
void vfcn();
};
void derived::vfcn()
{
cout << "Derived virtual fcn called.\n";
}
main()
{
derived* d = new derived;
d->vfcn();
delete d;
}
==================================================
Script started on Thu Dec 29 13:33:09 1988
gecrux% g++ -v -g -O -o bug bug.cc
g++ version 1.31.0
/usr/sculptorq/gnu/lib/gcc-cpp+ -v -undef -D__GNU__ -D__GNUG__ -Dmc68000 -Dsun -Dunix -D__OPTIMIZE__ bug.cc /tmp/cca01123.cpp
GNU CPP version 1.31.0
/usr/sculptorq/gnu/lib/gcc-c++ /tmp/cca01123.cpp -quiet -dumpbase bug.cc -opt -version -G -o /tmp/cca01123.s
GNU C++ version 1.31.0 (68k, MIT syntax) compiled by GNU C version 1.31.
as -mc68020 /tmp/cca01123.s -o bug.o
/usr/sculptorq/gnu/lib/gcc-ld++ -C -o bug /usr/sculptorq/gnu/lib/crt0+.o /lib/Fcrt1.o bug.o -lg++ /usr/sculptorq/gnu/lib/gcc-gnulib+ -lg -lc
gecrux% bug
Derived virtual fcn called.
Base destructor called.
This (base virtual fcn) shouldn't be called.
gecrux% ^D
script done on Thu Dec 29 13:34:33 1988
==================================================
I can localize the problem in the generated code:
==================================================
_main:
link a6,#0
movel a2,sp@-
clrl sp@-
jbsr _derived_PSderived
movel d0,a2
movel a2@(4),a0
movel a2,sp@-
movel a0@(4),a0
jbsr a0@
movel #__vt$base,a2@(4) <=== | ??? Why does g++ 1.31 want to make
pea 1:w | the derived class instance refer to
movel a2,sp@- | the base class virtual function table
jbsr __$_base | prior to calling the destructor ?
movel a6@(-4),a2
unlk a6
rts
--
Clark Cooper cooper@gecrux.steinmetz.ge.com, coopercc@crd.ge.com,
coopercc@ge-crd.arpa, ...!uunet!steinmetz!cooper