From: wje@hoffman.rstnu.bcm.tmc.edu (Bill Eaton)
Newsgroups: gnu.g++.bug
Subject: multiple inheritance abort
Date: 26 Jan 1993 22:18:21 -0500
Organization: GNUs Not Usenet
Distribution: gnu

gcc-2.3.3:  C++ bug, multiple inheritance and virtual functions can
lead to bad method calls.  It was observed on mips-sgi-irix4, but should
affect all platforms.

     Some combinations of multiple inheritance and virtual functions can
give rise to a bad virtual function table which results in unexpected
method calls.  A slight modification of the problem case gives an
"Internal compiler error" abort.  The original problem turned up in
InterViews 3.1 in the "doc" program involving class ItemView.

     The source file below will give the compiler abort.  Uncommenting the
indicated lines and recompiling will demonstrate the bad method calls.
The abort happens in modify_vtable_entry () from dereferencing a NULL
old_entry_in_list.

Call chain:  modify_vtable_entry, modify_vtable_entries,
add_virtual_function, finish_struct, yyparse, compile_file, main.

C++ source file inherit.cc
--------------------------------------------------
extern "C" {extern void printf (char*);}

typedef int boolean;
typedef int Requisition;

class Resource {
public:
    virtual void ref() const;
};

void Resource::ref () const { printf ("Resource::ref\n"); }



typedef int Event;

class Handler : public Resource {
public:
    virtual ~Handler ();
    virtual boolean event (Event&);
};

Handler::~Handler () { printf ("Handler destructor\n"); }
Handler::event (Event& e) { printf ("Handler::event\n"); return 1; }



class Glyph : public Resource {
public:
    virtual void request(Requisition&) const;
};

void Glyph::request (Requisition& r) const
{
  printf ("Glyph::request\n");
}



class MonoGlyph : public Glyph {
public:
// Uncommenting the line below allows this to compile, but gives a bad
// vtable for ItemView.

//  virtual ~MonoGlyph () { printf ("MonoGlyph destructor\n"); }
    virtual void request(Requisition&) const;

protected:
    MonoGlyph(Glyph* = 0);
};

MonoGlyph::MonoGlyph (Glyph* g) { ; }



void MonoGlyph::request (Requisition& r) const
{
  printf ("MonoGlyph::request\n");
}



class ItemView : public MonoGlyph, public Handler {
public:
    ItemView ();

    virtual boolean event (Event&);
};  // The "Internal compiler error" is seen here.

ItemView::ItemView () { ; }
ItemView::event (Event& e) { printf ("ItemView::event\n"); return 1; }



void foo (ItemView* v, Requisition& r)
{
  v->request (r);
}

int main (void)
{
  ItemView  i;
  Requisition r = 42;

  foo (&i, r);
  return 0;
}
--------------------------------------------------

% gcc -o inherit inherit.cc
inherit.cc:68: Internal compiler error.
inherit.cc:68: Please report this to `bug-g++@prep.ai.mit.edu'.

Uncommenting the ~MonoGlyph line and recompiling gives this:

% gcc -o inherit inherit.cc
% inherit
Handler destructor
MonoGlyph destructor
Handler destructor
MonoGlyph destructor

It should call MonoGlyph::request ().

Sorry, no patch included.
William J. Eaton, keeper of the Temple of Apollo Workstations
Email wje@hoffman.rstnu.bcm.tmc.edu   | If it looks like I know what I'm
Phone (713) 798-5161                  | doing, it's an optical illusion!
Dhvg ernqvat znvy be arjf naq trg onpx gb jbex!