class.c (dfs_unshared_virtual_bases): New function.

cp:
	* class.c (dfs_unshared_virtual_bases): New function.
	(mark_primary_bases): Call it.
	(check_bases): Ignore virtual bases when determining
	nearly-emptiness.
testsuite:
	* g++.old-deja/g++.abi/primary3.C (main): Correct expected layout.
	* g++.old-deja/g++.abi/crash1.C: New test.

From-SVN: r41295
This commit is contained in:
Nathan Sidwell 2001-04-12 07:44:48 +00:00 committed by Nathan Sidwell
parent bbb53468cc
commit 0fb3018cd8
5 changed files with 86 additions and 16 deletions

View file

@ -1,3 +1,10 @@
2001-04-12 Nathan Sidwell <nathan@codesourcery.com>
* class.c (dfs_unshared_virtual_bases): New function.
(mark_primary_bases): Call it.
(check_bases): Ignore virtual bases when determining
nearly-emptiness.
2001-04-12 Nathan Sidwell <nathan@codesourcery.com>
* method.c (make_thunk): Clear DECL_CLONED_FUNCTION.

View file

@ -190,6 +190,7 @@ static void build_vcall_and_vbase_vtbl_entries PARAMS ((tree,
vtbl_init_data *));
static void force_canonical_binfo_r PARAMS ((tree, tree, tree, tree));
static void force_canonical_binfo PARAMS ((tree, tree, tree, tree));
static tree dfs_unshared_virtual_bases PARAMS ((tree, void *));
static void mark_primary_bases PARAMS ((tree));
static tree mark_primary_virtual_base PARAMS ((tree, tree, tree));
static void clone_constructors_and_destructors PARAMS ((tree));
@ -1596,12 +1597,12 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
{
int n_baseclasses;
int i;
int seen_nearly_empty_base_p;
int seen_non_virtual_nearly_empty_base_p;
tree binfos;
binfos = TYPE_BINFO_BASETYPES (t);
n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
seen_nearly_empty_base_p = 0;
seen_non_virtual_nearly_empty_base_p = 0;
/* An aggregate cannot have baseclasses. */
CLASSTYPE_NON_AGGREGATE (t) |= (n_baseclasses != 0);
@ -1662,19 +1663,23 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
basetype);
}
/* If the base class is not empty or nearly empty, then this
class cannot be nearly empty. */
if (!CLASSTYPE_NEARLY_EMPTY_P (basetype) && !is_empty_class (basetype))
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
/* And if there is more than one nearly empty base, then the
derived class is not nearly empty either. */
else if (CLASSTYPE_NEARLY_EMPTY_P (basetype)
&& seen_nearly_empty_base_p)
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
/* If this is the first nearly empty base class, then remember
that we saw it. */
if (TREE_VIA_VIRTUAL (base_binfo))
/* A virtual base does not effect nearly emptiness. */
;
else if (CLASSTYPE_NEARLY_EMPTY_P (basetype))
seen_nearly_empty_base_p = 1;
{
if (seen_non_virtual_nearly_empty_base_p)
/* And if there is more than one nearly empty base, then the
derived class is not nearly empty either. */
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
else
/* Remember we've seen one. */
seen_non_virtual_nearly_empty_base_p = 1;
}
else if (!is_empty_class (basetype))
/* If the base class is not empty or nearly empty, then this
class cannot be nearly empty. */
CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
/* A lot of properties from the bases also apply to the derived
class. */
@ -1814,6 +1819,23 @@ mark_primary_virtual_base (binfo, base_binfo, type)
return base_binfo;
}
/* If BINFO is an unmarked virtual binfo for a class with a primary
base, then BINFO has no primary base in this graph. Called from
mark_primary_bases. */
static tree dfs_unshared_virtual_bases (binfo, data)
tree binfo;
void *data;
{
if (TREE_VIA_VIRTUAL (binfo) && !BINFO_MARKED (binfo)
&& CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
BINFO_LOST_PRIMARY_P (binfo) = 1;
CLEAR_BINFO_MARKED (binfo);
return NULL;
}
/* Set BINFO_PRIMARY_BASE_OF for all binfos in the hierarchy
dominated by TYPE that are primary bases. */
@ -1839,7 +1861,12 @@ mark_primary_bases (type)
if (base_binfo)
BINFO_PRIMARY_BASE_OF (base_binfo) = binfo;
SET_BINFO_MARKED (binfo);
}
/* There could remain unshared virtual bases which were not visited
in the inheritance graph walk. These bases will have lost their
primary base (should they have one). We must now find them. */
dfs_walk (TYPE_BINFO (type), dfs_unshared_virtual_bases, NULL, NULL);
}
/* Make the BINFO the primary base of T. */

View file

@ -1,3 +1,8 @@
2001-04-12 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.abi/primary3.C (main): Correct expected layout.
* g++.old-deja/g++.abi/crash1.C: New test.
2001-04-12 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.other/crash40.C: New test.

View file

@ -0,0 +1,21 @@
// Build don't link:
//
// Copyright (C) 2001 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 11 Apr 2001 <nathan@codesourcery.com>
// Bug 1944. We failed to calculate nearly emptiness properly, and
// lost primary too.
struct A1 {};
struct A2 {};
struct B1 : virtual A1 {};
struct B2 : virtual A2 {};
struct C1 : virtual B2 {};
struct C2 : virtual B2 {};
struct D1 : virtual C1, virtual C2 {};
struct D2 : virtual C2, virtual B1 {};
struct E : virtual D1, virtual D2 {};

View file

@ -21,14 +21,24 @@ int main ()
A *apd = &d;
B1 *b1pd = &d;
B2 *b2pd = &d;
C *cpd = &d;
#if __GXX_ABI_VERSION >= 100
if (static_cast <void *> (apc) != static_cast <void *> (b1pc))
return 1;
if (static_cast <void *> (apd) != static_cast <void *> (b1pd))
if (static_cast <void *> (&c) != static_cast <void *> (b2pc))
return 2;
if (static_cast <void *> (apd) != static_cast <void *> (&d))
if (static_cast <void *> (b1pc) == static_cast <void *> (b2pc))
return 3;
if (static_cast <void *> (apd) != static_cast <void *> (b1pd))
return 11;
if (static_cast <void *> (b2pd) != static_cast <void *> (&d))
return 12;
if (static_cast <void *> (b2pd) != static_cast <void *> (cpd))
return 13;
if (static_cast <void *> (b1pd) == static_cast <void *> (b2pd))
return 14;
#endif
return 0;
}