This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix bug 1701
- To: gcc-patches at gcc dot gnu dot org
- Subject: [C++ PATCH] Fix bug 1701
- From: Nathan Sidwell <nathan at codesourcery dot com>
- Date: Fri, 19 Jan 2001 13:35:18 +0000
- Organization: Codesourcery LLC
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;
}