This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

C++ PATCH: -frepo problem with classes using virtual derivation



hi -

I first reported this bug a while ago, but i've finally gotten around
to attempting a fix for it.

The problem was that sometimes template classes with virtual bases
were not being instantiated when -frepo is used.

For reference, i'm using egcs as checked out from cvs a couple days
ago (egcs-2.93.19 19990421) on a mips-sgi-irix6.5 platform

Here is a source which shows the problem:

-- tlist.cc ----------------------------------------------------------------

class d0_Collection_Base
{
public:
  virtual ~d0_Collection_Base () {}
};



template <class T>
class d0_Collection 
  : virtual public d0_Collection_Base
{
public:
  virtual void foo () {}
};




template <class T>
class d0_List_1
  : virtual public d0_Collection_Base
{
};



template <class T>
class d0_List
  : public d0_Collection<T>,
    public d0_List_1<T>
{
};



main ()
{
  d0_List<int> x;
}

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


And here's what happens when i try to compile it (starting with a
nonexistent .rpo file):

% g++ -c -frepo tlist.cc
% g++ -o tlist tlist.o
collect: recompiling tlist.cc
collect: relinking
ld32: WARNING 84: /local/data0/snyder/local/lib/gcc-lib/mips-sgi-irix6.5/egcs-2.93.19/libstdc++.a is not used for resolving any symbol.
ld32: WARNING 84: /usr/lib32/libm.so is not used for resolving any symbol.
ld32: ERROR 33: Unresolved text symbol "d0_List_1<int> type_info function" -- 1st referenced by tlist.o.
        Use linker option -v to see when and which objects, archives and dsos are loaded.  
ld32: ERROR 33: Unresolved text symbol "d0_List_1<int>::~d0_List_1(void)" -- 1st referenced by tlist.o.
        Use linker option -v to see when and which objects, archives and dsos are loaded.  
ld32: ERROR 33: Unresolved text symbol "d0_List_1<int>::d0_Collection_Base virtual table" -- 1st referenced by tlist.o.
        Use linker option -v to see when and which objects, archives and dsos are loaded.  
ld32: ERROR 33: Unresolved text symbol "d0_List_1<int> type_info node" -- 1st referenced by tlist.o.
        Use linker option -v to see when and which objects, archives and dsos are loaded.  
ld32: INFO 152: Output file removed because of error.
collect2: ld returned 2 exit status
%


The resulting .rpo file does not appear to have entries for the
missing symbols:

M tlist.cc
D /usr/local/home/snyder/gcc
A '-c' '-frepo'
O foo__t13d0_Collection1Zi
C _vt$t7d0_List1Zi
C _vt$t13d0_Collection1Zi


The problem seems to be in repo.c:repo_get_id, where it is trying
to get the vtable of a class with TYPE_BINFO_VTABLE.  The external name
of this vtable is what gets emitted to the .rpo file.  It looks like
not only the generation of the vtable but also the type info structures
and implicit functions are tied to this symbol.

But what happens in this case is that for the class d0_List_1<int>,
TYPE_BINFO_VTABLE is NULL_TREE.  This class does have virtual methods,
but they are all from virtual base classes.  So i extended repo_get_id,
so that if a class has a null TYPE_BINFO_VTABLE but does have
virtual bases, i search and see if any of the virtual bases has a vtable,
and if so, use the first one i find as the id.  (The logic for this
was basically copied from modify_all_indirect_vtables in class.c.)

I don't really understand the data structures representing derivation
here, so i'm not sure that this is really the correct thing to do.
However, it fixes this test case, and does not cause any testsuite
regressions.

thanks,
sss


1999-04-23  scott snyder  <snyder@fnal.gov>

	* repo.c (repo_get_id): Handle the case where a class with virtual 
	bases has a null TYPE_BINFO_VTABLE.

Index: repo.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/repo.c,v
retrieving revision 1.18
diff -u -p -r1.18 repo.c
--- repo.c	1999/03/26 07:44:49	1.18
+++ repo.c	1999/04/23 20:27:48
@@ -105,7 +105,34 @@ repo_get_id (t)
       if (TYPE_SIZE (t) == NULL_TREE || TYPE_BEING_DEFINED (t))
 	my_friendly_abort (981113);
 
-      t = TYPE_BINFO_VTABLE (t);
+      if (TYPE_BINFO_VTABLE (t) != NULL_TREE)
+        t = TYPE_BINFO_VTABLE (t);
+
+      else if (TYPE_USES_VIRTUAL_BASECLASSES (t))
+        {
+          tree binfo = TYPE_BINFO (t);
+          tree binfos = BINFO_BASETYPES (binfo);
+          if (binfos != 0)
+            {
+              int n_baselinks = TREE_VEC_LENGTH (binfos);
+              int i;
+              for (i = 0; i < n_baselinks; i++)
+                {
+                  tree base_binfo = TREE_VEC_ELT (binfos, i);
+                  if (TREE_VIA_VIRTUAL (base_binfo))
+                    {
+                      base_binfo = binfo_member (BINFO_TYPE (base_binfo), CLASSTYPE_VBASECLASSES (t));
+                      t = BINFO_VTABLE (base_binfo);
+                      if (t != 0)
+                        break;
+                    }
+                }
+            }
+        }
+
+      else
+        t = NULL_TREE;
+
       if (t == NULL_TREE)
 	return t;
     }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]