mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-23 02:00:32 +08:00
re PR c++/67407 (ice in friend_accessible_p)
PR c++/67407 * search.c (dfs_walk_once, dfs_walk_once_r) (dfs_walk_once_accessible_r, dfs_walk_once_accessible): Use hash_set instead of BINFO_MARKED. (dfs_unmark_r): Remove. From-SVN: r232929
This commit is contained in:
parent
e2eb505656
commit
e448880c20
@ -1,3 +1,11 @@
|
||||
2016-01-28 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/67407
|
||||
* search.c (dfs_walk_once, dfs_walk_once_r)
|
||||
(dfs_walk_once_accessible_r, dfs_walk_once_accessible): Use
|
||||
hash_set instead of BINFO_MARKED.
|
||||
(dfs_unmark_r): Remove.
|
||||
|
||||
2016-01-28 Patrick Palka <ppalka@gcc.gnu.org>
|
||||
|
||||
PR c++/24208
|
||||
|
@ -2608,9 +2608,7 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
|
||||
/* There was no existing virtual thunk (which takes
|
||||
precedence). So find the binfo of the base function's
|
||||
return type within the overriding function's return type.
|
||||
We cannot call lookup base here, because we're inside a
|
||||
dfs_walk, and will therefore clobber the BINFO_MARKED
|
||||
flags. Fortunately we know the covariancy is valid (it
|
||||
Fortunately we know the covariancy is valid (it
|
||||
has already been checked), so we can just iterate along
|
||||
the binfos, which have been chained in inheritance graph
|
||||
order. Of course it is lame that we have to repeat the
|
||||
|
@ -34,9 +34,6 @@ static tree dfs_lookup_base (tree, void *);
|
||||
static tree dfs_dcast_hint_pre (tree, void *);
|
||||
static tree dfs_dcast_hint_post (tree, void *);
|
||||
static tree dfs_debug_mark (tree, void *);
|
||||
static tree dfs_walk_once_r (tree, tree (*pre_fn) (tree, void *),
|
||||
tree (*post_fn) (tree, void *), void *data);
|
||||
static void dfs_unmark_r (tree);
|
||||
static int check_hidden_convs (tree, int, int, tree, tree, tree);
|
||||
static tree split_conversions (tree, tree, tree, tree);
|
||||
static int lookup_conversions_r (tree, int, int,
|
||||
@ -44,10 +41,6 @@ static int lookup_conversions_r (tree, int, int,
|
||||
static int look_for_overrides_r (tree, tree);
|
||||
static tree lookup_field_r (tree, void *);
|
||||
static tree dfs_accessible_post (tree, void *);
|
||||
static tree dfs_walk_once_accessible_r (tree, bool, bool,
|
||||
tree (*pre_fn) (tree, void *),
|
||||
tree (*post_fn) (tree, void *),
|
||||
void *data);
|
||||
static tree dfs_walk_once_accessible (tree, bool,
|
||||
tree (*pre_fn) (tree, void *),
|
||||
tree (*post_fn) (tree, void *),
|
||||
@ -1826,7 +1819,8 @@ dfs_walk_all (tree binfo, tree (*pre_fn) (tree, void *),
|
||||
|
||||
static tree
|
||||
dfs_walk_once_r (tree binfo, tree (*pre_fn) (tree, void *),
|
||||
tree (*post_fn) (tree, void *), void *data)
|
||||
tree (*post_fn) (tree, void *), hash_set<tree> *pset,
|
||||
void *data)
|
||||
{
|
||||
tree rval;
|
||||
unsigned ix;
|
||||
@ -1849,13 +1843,10 @@ dfs_walk_once_r (tree binfo, tree (*pre_fn) (tree, void *),
|
||||
for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
|
||||
{
|
||||
if (BINFO_VIRTUAL_P (base_binfo))
|
||||
{
|
||||
if (BINFO_MARKED (base_binfo))
|
||||
continue;
|
||||
BINFO_MARKED (base_binfo) = 1;
|
||||
}
|
||||
if (pset->add (base_binfo))
|
||||
continue;
|
||||
|
||||
rval = dfs_walk_once_r (base_binfo, pre_fn, post_fn, data);
|
||||
rval = dfs_walk_once_r (base_binfo, pre_fn, post_fn, pset, data);
|
||||
if (rval)
|
||||
return rval;
|
||||
}
|
||||
@ -1872,30 +1863,6 @@ dfs_walk_once_r (tree binfo, tree (*pre_fn) (tree, void *),
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Worker for dfs_walk_once. Recursively unmark the virtual base binfos of
|
||||
BINFO. */
|
||||
|
||||
static void
|
||||
dfs_unmark_r (tree binfo)
|
||||
{
|
||||
unsigned ix;
|
||||
tree base_binfo;
|
||||
|
||||
/* Process the basetypes. */
|
||||
for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
|
||||
{
|
||||
if (BINFO_VIRTUAL_P (base_binfo))
|
||||
{
|
||||
if (!BINFO_MARKED (base_binfo))
|
||||
continue;
|
||||
BINFO_MARKED (base_binfo) = 0;
|
||||
}
|
||||
/* Only walk, if it can contain more virtual bases. */
|
||||
if (CLASSTYPE_VBASECLASSES (BINFO_TYPE (base_binfo)))
|
||||
dfs_unmark_r (base_binfo);
|
||||
}
|
||||
}
|
||||
|
||||
/* Like dfs_walk_all, except that binfos are not multiply walked. For
|
||||
non-diamond shaped hierarchies this is the same as dfs_walk_all.
|
||||
For diamond shaped hierarchies we must mark the virtual bases, to
|
||||
@ -1918,22 +1885,8 @@ dfs_walk_once (tree binfo, tree (*pre_fn) (tree, void *),
|
||||
rval = dfs_walk_all (binfo, pre_fn, post_fn, data);
|
||||
else
|
||||
{
|
||||
rval = dfs_walk_once_r (binfo, pre_fn, post_fn, data);
|
||||
if (!BINFO_INHERITANCE_CHAIN (binfo))
|
||||
{
|
||||
/* We are at the top of the hierarchy, and can use the
|
||||
CLASSTYPE_VBASECLASSES list for unmarking the virtual
|
||||
bases. */
|
||||
vec<tree, va_gc> *vbases;
|
||||
unsigned ix;
|
||||
tree base_binfo;
|
||||
|
||||
for (vbases = CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)), ix = 0;
|
||||
vec_safe_iterate (vbases, ix, &base_binfo); ix++)
|
||||
BINFO_MARKED (base_binfo) = 0;
|
||||
}
|
||||
else
|
||||
dfs_unmark_r (binfo);
|
||||
hash_set<tree> pset;
|
||||
rval = dfs_walk_once_r (binfo, pre_fn, post_fn, &pset, data);
|
||||
}
|
||||
|
||||
active--;
|
||||
@ -1947,7 +1900,7 @@ dfs_walk_once (tree binfo, tree (*pre_fn) (tree, void *),
|
||||
indicates whether bases should be marked during traversal. */
|
||||
|
||||
static tree
|
||||
dfs_walk_once_accessible_r (tree binfo, bool friends_p, bool once,
|
||||
dfs_walk_once_accessible_r (tree binfo, bool friends_p, hash_set<tree> *pset,
|
||||
tree (*pre_fn) (tree, void *),
|
||||
tree (*post_fn) (tree, void *), void *data)
|
||||
{
|
||||
@ -1971,9 +1924,9 @@ dfs_walk_once_accessible_r (tree binfo, bool friends_p, bool once,
|
||||
/* Find the next child binfo to walk. */
|
||||
for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
|
||||
{
|
||||
bool mark = once && BINFO_VIRTUAL_P (base_binfo);
|
||||
bool mark = pset && BINFO_VIRTUAL_P (base_binfo);
|
||||
|
||||
if (mark && BINFO_MARKED (base_binfo))
|
||||
if (mark && pset->contains (base_binfo))
|
||||
continue;
|
||||
|
||||
/* If the base is inherited via private or protected
|
||||
@ -1992,9 +1945,9 @@ dfs_walk_once_accessible_r (tree binfo, bool friends_p, bool once,
|
||||
}
|
||||
|
||||
if (mark)
|
||||
BINFO_MARKED (base_binfo) = 1;
|
||||
pset->add (base_binfo);
|
||||
|
||||
rval = dfs_walk_once_accessible_r (base_binfo, friends_p, once,
|
||||
rval = dfs_walk_once_accessible_r (base_binfo, friends_p, pset,
|
||||
pre_fn, post_fn, data);
|
||||
if (rval)
|
||||
return rval;
|
||||
@ -2021,28 +1974,14 @@ dfs_walk_once_accessible (tree binfo, bool friends_p,
|
||||
tree (*pre_fn) (tree, void *),
|
||||
tree (*post_fn) (tree, void *), void *data)
|
||||
{
|
||||
bool diamond_shaped = CLASSTYPE_DIAMOND_SHAPED_P (BINFO_TYPE (binfo));
|
||||
tree rval = dfs_walk_once_accessible_r (binfo, friends_p, diamond_shaped,
|
||||
hash_set<tree> *pset = NULL;
|
||||
if (CLASSTYPE_DIAMOND_SHAPED_P (BINFO_TYPE (binfo)))
|
||||
pset = new hash_set<tree>;
|
||||
tree rval = dfs_walk_once_accessible_r (binfo, friends_p, pset,
|
||||
pre_fn, post_fn, data);
|
||||
|
||||
if (diamond_shaped)
|
||||
{
|
||||
if (!BINFO_INHERITANCE_CHAIN (binfo))
|
||||
{
|
||||
/* We are at the top of the hierarchy, and can use the
|
||||
CLASSTYPE_VBASECLASSES list for unmarking the virtual
|
||||
bases. */
|
||||
vec<tree, va_gc> *vbases;
|
||||
unsigned ix;
|
||||
tree base_binfo;
|
||||
|
||||
for (vbases = CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)), ix = 0;
|
||||
vec_safe_iterate (vbases, ix, &base_binfo); ix++)
|
||||
BINFO_MARKED (base_binfo) = 0;
|
||||
}
|
||||
else
|
||||
dfs_unmark_r (binfo);
|
||||
}
|
||||
if (pset)
|
||||
delete pset;
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
51
gcc/testsuite/g++.dg/inherit/protected1.C
Normal file
51
gcc/testsuite/g++.dg/inherit/protected1.C
Normal file
@ -0,0 +1,51 @@
|
||||
// PR c++/67407
|
||||
|
||||
template <class> class A;
|
||||
template <class> struct B;
|
||||
template <class X> struct B<A<X> >
|
||||
{
|
||||
static int
|
||||
check ()
|
||||
{
|
||||
A<X> a;
|
||||
a.m_class->m_object;
|
||||
}
|
||||
};
|
||||
template <class T> class A
|
||||
{
|
||||
public:
|
||||
template <class X> bool operator== (const X &) const;
|
||||
T *m_class;
|
||||
};
|
||||
template <class T>
|
||||
template <class X>
|
||||
bool
|
||||
A<T>::operator== (const X &) const
|
||||
{
|
||||
B<X>::check;
|
||||
}
|
||||
class C
|
||||
{
|
||||
protected:
|
||||
template <class> friend struct B;
|
||||
void *m_object;
|
||||
};
|
||||
class F : virtual C
|
||||
{
|
||||
};
|
||||
class G : virtual public C
|
||||
{
|
||||
};
|
||||
class H : F, public G
|
||||
{
|
||||
};
|
||||
class D
|
||||
{
|
||||
void onBusMessage (const A<int> &);
|
||||
A<H> m_pipeline;
|
||||
};
|
||||
void
|
||||
D::onBusMessage (const A<int> &p1)
|
||||
{
|
||||
p1 == m_pipeline;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user