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]

[RFA:] Fix for some .vtable_inherit inheritance bugs in the "old"ABI.


I've tried to fix *some* bugs in the -fvtable-gc machinery.  Here's a
patch for incorrent .vt_inherit output; it was previously naming the
*most* derived class, while we want the *least* derived class.  E.g. for
"class A {}; class B : A {}; class C : B {};" it should say
".vtable_inherit .vt.C, .vt.B", not ".vtable_inherit .vt.C, .vt.A".  It
also did not work for virtual bases.  I'm somewhat lost among the trees,
so this patch might not catch all cases or have other flaws obvious to C++
foresters.  Note that binfo_for_vtable seems to be only used for finding
the right data for the vtable_inherit output, so this shouldn't be in any
normal code path.

Sad to say, this does not work for the new ABI.  Neither did it before, to
the same extent or slightly less.  There seems to be too large general
differences for -fvtable-gc to work at present with the new ABI.  For
example, a vt with the new ABI looks can "inherit" from several other
vt:s on different inheritance paths, and the .vtable_entry offsets seem like
they need an extra offset unknown at the call site.  See also
<URL:http://gcc.gnu.org/ml/gcc/1999-08n/msg00905.html>.  I hope and
believe this can be fixed, perhaps with the help of some extra .vtable_foo
machinery.

Perhaps using -fvtable-gc should be an error, or warned about for the new ABI?

Is there other documentation for the new ABI than the code and mailing
list contents?  Something to add to readings.html?

Bootstrapped and checked on i686-pc-linux-gnulibc1 with no new regressions.
I did a "make check-g++ 'RUNTESTFLAGS=--tool_opts -fvtable-gc'" run to
ensure that gcc does not SEGV or catch a check-error.  Note that using
-fvtable-gc generally fails frequently with the invalid-asm-operands 
message as reported, but I don't have enough clues how to fix that, so I
might have to leave it to Somebody Else.

Ok to commit?

gcc/cp:
	* search.c (binfo_for_vtable): Return least derived class, not
	most.  Handle secondary vtables.

testsuite: (using previous posted bits of g++.dg machinery)
	* g++.dg/vtgc1.C: New test.

Index: search.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/search.c,v
retrieving revision 1.188
diff -p -c -r1.188 search.c
*** search.c	2000/09/05 00:57:57	1.188
--- search.c	2000/10/08 20:23:02
*************** types_overlap_p (empty_type, next_type)
*** 3348,3367 ****
    return oi.found_overlap;
  }
  
! /* Given a vtable VAR, determine which binfo it comes from.
  
!    FIXME What about secondary vtables?  */
  
  tree
  binfo_for_vtable (var)
       tree var;
  {
!   tree binfo = TYPE_BINFO (DECL_CONTEXT (var));
  
!   while (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
!     binfo = get_primary_binfo (binfo);
  
!   return binfo;
  }
  
  /* Returns 1 iff BINFO is from a direct or indirect virtual base.  */
--- 3348,3380 ----
    return oi.found_overlap;
  }
  
! /* Given a vtable VAR, determine which of the inherited classes the vtable
!    inherits (in a loose sense) functions from.
  
!    FIXME: This does not work with the new ABI.  */
  
  tree
  binfo_for_vtable (var)
       tree var;
  {
!   tree main_binfo = TYPE_BINFO (DECL_CONTEXT (var));
!   tree binfos = TYPE_BINFO_BASETYPES (BINFO_TYPE (main_binfo));
!   int n_baseclasses = CLASSTYPE_N_BASECLASSES (BINFO_TYPE (main_binfo));
!   int i;
  
!   for (i = 0; i < n_baseclasses; i++)
!     {
!       tree base_binfo = TREE_VEC_ELT (binfos, i);
!       if (base_binfo != NULL_TREE && BINFO_VTABLE (base_binfo) == var)
! 	return base_binfo;
!     }
  
!   /* If no secondary base classes matched, return the primary base, if
!      there is one.   */
!   if (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (main_binfo)))
!     return get_primary_binfo (main_binfo);
! 
!   return main_binfo;
  }
  
  /* Returns 1 iff BINFO is from a direct or indirect virtual base.  */

*** /dev/null	Tue Jan  1 05:00:00 1980
--- vtgc1.C	Sun Oct  8 22:28:21 2000
***************
*** 0 ****
--- 1,135 ----
+ // { dg-do compile }
+ // { dg-options "-fvtable-gc -fno-new-abi" }
+ // Origin: Hans-Peter Nilsson <hp@bitrange.com>
+ 
+ class Base0
+ {
+ public:
+   Base0(); virtual ~Base0();
+   virtual void f1();
+   virtual void f2();
+ private:
+   int a_value;
+ };
+ 
+ class Base1 : public Base0
+ {
+ public:
+   Base1(); virtual ~Base1();
+   virtual void f1(), f2();
+   virtual void f3();
+ };
+ 
+ class Base2 : public Base1
+ {
+ public:
+   Base2(); virtual ~Base2();
+   virtual void f1(), f2();
+   virtual void f4();
+ };
+ 
+ class VbasedA : virtual public Base2
+ {
+ public:
+   VbasedA(); virtual ~VbasedA();
+   virtual void f1(), f2(), f3();
+   virtual void f6();
+ };
+ 
+ class Side0
+ {
+ public:
+   Side0(); virtual ~Side0();
+   virtual void x1();
+   virtual void xx();
+ private:
+   int ryan;
+ };
+ 
+ class Multisv0 : public Side0, virtual public Base2
+ {
+ public:
+   Multisv0(); virtual ~Multisv0();
+   virtual void f1(), f2();
+   virtual void f3();
+   virtual void f6();
+   virtual void xx();
+ };
+ 
+ class Multivs1 : public Base2, virtual public Side0
+ {
+ public:
+   Multivs1(); virtual ~Multivs1(); virtual void f1(); virtual void fx2();
+   virtual void fx4(), fx5();
+   virtual void f6();
+   virtual void xx();
+ };
+ 
+ class Multiss2 : public Base2, public Side0
+ {
+ public:
+   Multiss2(); virtual ~Multiss2(); virtual void f1(); virtual void fx2();
+   virtual void fx4();
+   virtual void f6();
+   virtual void xx();
+ };
+ 
+ class Multivv3 : virtual public Base2, virtual public Side0
+ {
+ public:
+   Multivv3(); virtual ~Multivv3(); virtual void f1(); virtual void fx2();
+   virtual void fx4(), fx5();
+   virtual void f6();
+   virtual void xx();
+ };
+ 
+ Base0::Base0() {}
+ Base0::~Base0() {}
+ Base1::Base1() {}
+ Base1::~Base1() {}
+ Base2::Base2() {}
+ Base2::~Base2() {}
+ VbasedA::VbasedA() {}
+ VbasedA::~VbasedA() {}
+ Multisv0::Multisv0() {}
+ Multisv0::~Multisv0() {}
+ Multivs1::Multivs1() {}
+ Multivs1::~Multivs1() {}
+ Multiss2::Multiss2() {}
+ Multiss2::~Multiss2() {}
+ Multivv3::Multivv3() {}
+ Multivv3::~Multivv3() {}
+ Side0::Side0() {}
+ Side0::~Side0() {}
+ 
+ extern void x (VbasedA *);
+ extern void x2 (Multisv0 *);
+ extern void x3 (Multivs1 *);
+ extern void x4 (Multiss2 *);
+ extern void x5 (Multivv3 *);
+ void y () { VbasedA ii; x(&ii);}
+ void y2 () { Multisv0 ii; x2(&ii);}
+ void y3 () { Multivs1 ii; x3(&ii);}
+ void y4 () { Multiss2 ii; x4(&ii);}
+ void y5 () { Multivv3 ii; x5(&ii);}
+ void x (VbasedA *ii) { ii->f2();}
+ void x2 (Multisv0 *ii) { ii->f2();}
+ void x3 (Multivs1 *ii) { ii->f2();}
+ void x4 (Multiss2 *ii) { ii->f2();}
+ void x5 (Multivv3 *ii) { ii->f2();}
+ 
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*Multivv3 virtual table, 0" } }
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*Multivv3::Side0 virtual table, Side0 virtual table" } }
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*Multivv3::Base2 virtual table, Base2 virtual table" } }
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*Multiss2 virtual table, Base2 virtual table" } }
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*Multiss2::Side0 virtual table, Side0 virtual table" } }
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*Multivs1 virtual table, Base2 virtual table" } }
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*Multivs1::Side0 virtual table, Side0 virtual table" } }
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*Multisv0 virtual table, Side0 virtual table" } }
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*Multisv0::Base2 virtual table, Base2 virtual table" } }
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*Side0 virtual table, 0" } }
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*VbasedA virtual table, 0" } }
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*VbasedA::Base2 virtual table, Base2 virtual table" } }
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*Base2 virtual table, Base1 virtual table" } }
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*Base1 virtual table, Base0 virtual table" } }
+ // { dg-final { scan-assembler-dem vtgc1.C "\.vtable_inherit\[ \t\]*Base0 virtual table, 0" } }

brgds, H-P


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