[gnu.g++.bug] G++ 1.31 doesn't call proper virtual function

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