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] Fix bug 1701


Hi,
I've installed this obvious fix for bug 1701. This also happens to be an
optimization.

get_vbase_1 uses a `clever' algorithm to locate a virtual base by
going through the fewest virtual bases. Unfortunately it's the _wrong_
clever algorithm. Normally that just pessimizes code, as we have more
indirections. During object construction however, those other virtual
bases may not have been initialized yet.

built & tested on i686-pc-linux-gnu.

nathan
-- 
Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2001-01-19  Nathan Sidwell  <nathan@codesourcery.com>

	* search.c (get_vbase_1): Count only virtual bases.

Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/search.c,v
retrieving revision 1.197
diff -c -3 -p -r1.197 search.c
*** search.c	2001/01/03 15:01:16	1.197
--- search.c	2001/01/19 13:07:42
*************** get_vbase_1 (parent, binfo, depth)
*** 193,207 ****
    tree binfos;
    int i, n_baselinks;
    tree rval = NULL_TREE;
  
!   if (BINFO_TYPE (binfo) == parent && TREE_VIA_VIRTUAL (binfo))
      {
        *depth = 0;
        return binfo;
      }
  
-   *depth = *depth - 1;
- 
    binfos = BINFO_BASETYPES (binfo);
    n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  
--- 193,207 ----
    tree binfos;
    int i, n_baselinks;
    tree rval = NULL_TREE;
+   int virtualp = TREE_VIA_VIRTUAL (binfo) != 0;
  
!   *depth -= virtualp;
!   if (virtualp && BINFO_TYPE (binfo) == parent)
      {
        *depth = 0;
        return binfo;
      }
  
    binfos = BINFO_BASETYPES (binfo);
    n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  
*************** get_vbase_1 (parent, binfo, depth)
*** 218,224 ****
        if (nrval)
  	rval = nrval;
      }
!   *depth = *depth+1;
    return rval;
  }
  
--- 218,224 ----
        if (nrval)
  	rval = nrval;
      }
!   *depth += virtualp;
    return rval;
  }
  
// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 19 Jan 2001 <nathan@codesourcery.com>

// Bug 1701. building a vbase path was not using the shortest number of
// vbases. Normally that's just a pessimization, unfortunately during
// constructoring it leads to uninitialized reads.

extern "C" int printf (...);

int fail = 0;

/*{{{  struct Base*/
struct Base
{
  unsigned m;
  static Base *addr;
  
  Base ();
  virtual ~Base ();
};
/*}}}*/
Base *Base::addr;
/*{{{  Base::Base ()*/
Base::Base ()
{
  printf ("Base (%u) ctor %x\n", sizeof (Base), this);
  if (fail) ;
  else if (addr)
    fail = 1;
  else
    addr = this;
}
/*}}}*/
/*{{{  Base::~Base ()*/
Base::~Base ()
{
  printf ("Base dtor %x\n", this);
  if (fail)
    ;
  else if (this != addr)
    fail = 2;
  else
    addr = 0;
}
/*}}}*/

/*{{{  struct M10 : virtual Base*/
struct M10 : virtual Base
{
  int m;
  static M10 *addr;
  
  M10 ();
  virtual ~M10 ();
};
/*}}}*/
M10 *M10::addr;
/*{{{  M10::M10 ()*/
M10::M10 ()
{
  printf ("M10 (%u) ctor %x\n", sizeof (M10), this);
  if (fail) ;
  else if (addr)
    fail = 3;
  else
    addr = this;
}
/*}}}*/
/*{{{  M10::~M10 ()*/
M10::~M10 ()
{
  printf ("M10 dtor %x\n", this);
  if (fail)
    ;
  else if (this != addr)
    fail = 4;
  else
    addr = 0;
}
/*}}}*/

/*{{{  struct M4 : virtual Base, virtual M10*/
struct M4 : virtual Base, virtual M10
{
  int m;
  static M4 *addr;
  
  M4 ();
  virtual ~M4 ();
};
/*}}}*/
M4 *M4::addr;
/*{{{  M4::M4 ()*/
M4::M4 ()
{
  printf ("M4 (%u) ctor %x\n", sizeof (M4), this);
  if (fail) ;
  else if (addr)
    fail = 5;
  else
    addr = this;
}
/*}}}*/
/*{{{  M4::~M4 ()*/
M4::~M4 ()
{
  printf ("M4 dtor %x\n", this);
  if (fail)
    ;
  else if (this != addr)
    fail = 6;
  else
    addr = 0;
}
/*}}}*/

/*{{{  struct M5 : M4*/
struct M5 : M4
{
  int m;
  static M5 *addr;
  
  M5 ();
  virtual ~M5 ();
};
/*}}}*/
M5 *M5::addr;
/*{{{  M5::M5 ()*/
M5::M5 ()
{
  printf ("M5 (%u) ctor %x\n", sizeof (M5), this);
  if (fail) ;
  else if (addr)
    fail = 7;
  else
    addr = this;
}
/*}}}*/
/*{{{  M5::~M5 ()*/
M5::~M5 ()
{
  printf ("M5 dtor %x\n", this);
  if (fail)
    ;
  else if (this != addr)
    fail = 8;
  else
    addr = 0;
}
/*}}}*/

/*{{{  struct M9 : M5, virtual M10*/
struct M9 : M5, virtual M10
{
  int m;
  static M9 *addr;
  
  M9 ();
  virtual ~M9 ();
};
/*}}}*/
M9 *M9::addr;
/*{{{  M9::M9 ()*/
M9::M9 ()
{
  printf ("M9 (%u), ctor %x\n", sizeof (M9), this);
  if (fail) ;
  else if (addr)
    fail = 9;
  else
    addr = this;
}
/*}}}*/
/*{{{  M9::~M9 ()*/
M9::~M9 ()
{
  printf ("M9 dtor %x\n", this);
  if (fail)
    ;
  else if (this != addr)
    fail = 10;
  else
    addr = 0;
}
/*}}}*/

int main ()
{
  M9 *m9;
  Base *r;
  
  m9 = new M9 ();
  r = m9;
  if (fail)
    return fail;
  void *top = dynamic_cast <void *> (r);
  if (top != m9)
    return 20;
  r->~Base ();
  
  return fail;
}

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