vtable instantiation problem with egcs-ss-970814

scott snyder snyder@d0sgif.fnal.gov
Wed Apr 21 15:15:00 GMT 1999


hi -

The following applies to egcs version `egcs-2.90.00 970814'
on a `mips-sgi-irix5.3' system.  (This problem was also present
in cygnus-2.7.2-970404.)

When using the template repository, gcc will sometimes fail to emit
the vtable for a template class, even when it is specifically chosen
in the .rpo file.

Here is an example:

-- d0_PList.cc ------------------------------------------------------------

template <class T>
class d0om_STL_Iterator_Base
{
public:
  virtual ~d0om_STL_Iterator_Base () {}
};


template <class T>
class d0_List_1
{
public:
  void _d0_begin ();
};

template <class T>
void d0_List_1<T>::_d0_begin ()
{
  new d0om_STL_Iterator_Base<T> ();
}


template class d0_List_1<void*>;

---------------------------------------------------------------------------

Then build this as follows.

First compile:

  cc1plus -frepo d0_PList.cc

The .rpo file produced looks like:

M d0_PList.cc
D /d0sgif/data1/snyder/tmp
O _vt$t22d0om_STL_Iterator_Base1ZPv
C _d0_begin__t9d0_List_11ZPv


Edit the .rpo file and change the `O' in front of the vtab symbol
to a `C'.  Then recompile:

  cc1plus -frepo d0_PList.cc

The edit of the .rpo file _should_ have told gcc to emit the vtab in this
file, but it does not:

% grep _vt d0_PList.s
        la      $2,_vt$t22d0om_STL_Iterator_Base1ZPv

The .rpo file is unchanged by the compilation:

M d0_PList.cc
D /d0sgif/data1/snyder/tmp
C _vt$t22d0om_STL_Iterator_Base1ZPv
C _d0_begin__t9d0_List_11ZPv



Poking around a bit with the debugger, it looks like where the repo
information for a vtab gets noticed is when instantiate_class_template()
calls repo_function_used().  However, this occurs _after_ a call
to finish_prevtable_vardecl().  This in turn calls import_export_template().
At this point the `interface_unknown' flag is set in the class type,
so inport_export_template() turns it on and disables writing the vtable.
Next, import_export_vtable() is called, which freezes this information
in the vtable type node.  Thus, when the repo information is actually
noticed, it is too late to make a difference.

I tried a quick fix for this by putting another call to
repo_template_used() before finish_prevtable_vardecl() in
instantiate_class_template().  (I wasn't sure if the original call
could be safely removed.)  This works for the above program.
It also seems to work correctly for a much more complicated
program, where i had previously been getting lots of undefined
vtables.

Here's the diff:

--- pt.c-orig   Sun Aug 17 01:11:16 1997
+++ pt.c        Sun Aug 17 01:12:19 1997
@@ -1321,6 +1321,9 @@
 
       type = finish_struct_1 (type, 0);
       CLASSTYPE_GOT_SEMICOLON (type) = 1;
+      /* sss - need to take into accout repo info for the vtab
+               before doing the final import_export_vtable. */
+      repo_template_used (type);
       if (at_eof && TYPE_BINFO_VTABLE (type) != NULL_TREE)
        finish_prevtable_vardecl (NULL, TYPE_BINFO_VTABLE (type));
 

thanks,
sss
snyder@fnald0.fnal.gov


More information about the Gcc-bugs mailing list