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