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