re PR ipa/60871 (internal compiler error: in possible_polymorphic_call_targets, at ipa-devirt.c:1510)
PR ipa/60871 PR ipa/64139 * tree.c (lookup_binfo_at_offset): New function. (get_binfo_at_offset): Use it. * g++.dg/torture/pr64139.C: New testcase. * g++.dg/torture/pr60871.C: Likewise. From-SVN: r220185
This commit is contained in:
parent
94e54b8d14
commit
e23f28927f
|
@ -1,3 +1,10 @@
|
|||
2015-01-27 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
PR ipa/60871
|
||||
PR ipa/64139
|
||||
* tree.c (lookup_binfo_at_offset): New function.
|
||||
(get_binfo_at_offset): Use it.
|
||||
|
||||
2015-01-27 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
PR ipa/64282
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2015-01-27 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
PR ipa/60871
|
||||
PR ipa/64139
|
||||
* g++.dg/torture/pr64139.C: New testcase.
|
||||
* g++.dg/torture/pr60871.C: Likewise.
|
||||
|
||||
2015-01-27 Janus Weil <janus@gcc.gnu.org>
|
||||
|
||||
PR fortran/64230
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/* { dg-do compile } */
|
||||
struct A
|
||||
{
|
||||
virtual void m_fn1 ();
|
||||
int m_local;
|
||||
};
|
||||
class C : virtual public A
|
||||
{
|
||||
};
|
||||
struct B
|
||||
{
|
||||
A *m_g;
|
||||
|
||||
B (A *p1) : m_g (p1) { m_g->m_fn1 (); }
|
||||
};
|
||||
struct C7
|
||||
{
|
||||
virtual ~C7 ();
|
||||
};
|
||||
class D : public C, C7
|
||||
{
|
||||
};
|
||||
struct F : D
|
||||
{
|
||||
F (int);
|
||||
|
||||
static void m_fn2 ()
|
||||
{
|
||||
F a (0);
|
||||
B b (&a);
|
||||
}
|
||||
};
|
||||
void fn1 () { F::m_fn2 (); }
|
|
@ -0,0 +1,34 @@
|
|||
// { dg-do compile }
|
||||
class IObject {
|
||||
public:
|
||||
virtual ~IObject();
|
||||
};
|
||||
class A {
|
||||
virtual int m_fn1();
|
||||
};
|
||||
class B {
|
||||
public:
|
||||
virtual int m_fn2(B) const;
|
||||
};
|
||||
class D : IObject, public virtual B {};
|
||||
class G : public D, A {
|
||||
public:
|
||||
G(A);
|
||||
};
|
||||
class F : B {
|
||||
friend class C;
|
||||
};
|
||||
class C {
|
||||
void m_fn3(const IObject &, int &);
|
||||
void m_fn4(const B &, int &);
|
||||
};
|
||||
A a;
|
||||
void C::m_fn3(const IObject &, int &p2) {
|
||||
G r(a);
|
||||
m_fn4(r, p2);
|
||||
}
|
||||
void C::m_fn4(const B &p1, int &) {
|
||||
F b;
|
||||
p1.m_fn2(b);
|
||||
}
|
||||
|
67
gcc/tree.c
67
gcc/tree.c
|
@ -11990,6 +11990,23 @@ type_in_anonymous_namespace_p (const_tree t)
|
|||
return (TYPE_STUB_DECL (t) && !TREE_PUBLIC (TYPE_STUB_DECL (t)));
|
||||
}
|
||||
|
||||
/* Lookup sub-BINFO of BINFO of TYPE at offset POS. */
|
||||
|
||||
tree
|
||||
lookup_binfo_at_offset (tree binfo, tree type, HOST_WIDE_INT pos)
|
||||
{
|
||||
unsigned int i;
|
||||
tree base_binfo, b;
|
||||
|
||||
for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
|
||||
if (pos == tree_to_shwi (BINFO_OFFSET (base_binfo))
|
||||
&& types_same_for_odr (TREE_TYPE (base_binfo), type))
|
||||
return base_binfo;
|
||||
else if ((b = lookup_binfo_at_offset (base_binfo, type, pos)) != NULL)
|
||||
return b;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Try to find a base info of BINFO that would have its field decl at offset
|
||||
OFFSET within the BINFO type and which is of EXPECTED_TYPE. If it can be
|
||||
found, return, otherwise return NULL_TREE. */
|
||||
|
@ -12027,42 +12044,22 @@ get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type)
|
|||
represented in the binfo for the derived class. */
|
||||
else if (offset != 0)
|
||||
{
|
||||
tree base_binfo, binfo2 = binfo;
|
||||
tree found_binfo = NULL, base_binfo;
|
||||
int offset = (tree_to_shwi (BINFO_OFFSET (binfo)) + pos
|
||||
/ BITS_PER_UNIT);
|
||||
|
||||
/* Find BINFO corresponding to FLD. This is bit harder
|
||||
by a fact that in virtual inheritance we may need to walk down
|
||||
the non-virtual inheritance chain. */
|
||||
while (true)
|
||||
{
|
||||
tree containing_binfo = NULL, found_binfo = NULL;
|
||||
for (i = 0; BINFO_BASE_ITERATE (binfo2, i, base_binfo); i++)
|
||||
if (types_same_for_odr (TREE_TYPE (base_binfo), TREE_TYPE (fld)))
|
||||
{
|
||||
found_binfo = base_binfo;
|
||||
break;
|
||||
}
|
||||
else
|
||||
if ((tree_to_shwi (BINFO_OFFSET (base_binfo))
|
||||
- tree_to_shwi (BINFO_OFFSET (binfo)))
|
||||
* BITS_PER_UNIT < pos
|
||||
/* Rule out types with no virtual methods or we can get confused
|
||||
here by zero sized bases. */
|
||||
&& TYPE_BINFO (BINFO_TYPE (base_binfo))
|
||||
&& BINFO_VTABLE (TYPE_BINFO (BINFO_TYPE (base_binfo)))
|
||||
&& (!containing_binfo
|
||||
|| (tree_to_shwi (BINFO_OFFSET (containing_binfo))
|
||||
< tree_to_shwi (BINFO_OFFSET (base_binfo)))))
|
||||
containing_binfo = base_binfo;
|
||||
if (found_binfo)
|
||||
{
|
||||
binfo = found_binfo;
|
||||
break;
|
||||
}
|
||||
if (!containing_binfo)
|
||||
return NULL_TREE;
|
||||
binfo2 = containing_binfo;
|
||||
}
|
||||
}
|
||||
for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
|
||||
if (tree_to_shwi (BINFO_OFFSET (base_binfo)) == offset
|
||||
&& types_same_for_odr (TREE_TYPE (base_binfo), TREE_TYPE (fld)))
|
||||
{
|
||||
found_binfo = base_binfo;
|
||||
break;
|
||||
}
|
||||
if (found_binfo)
|
||||
binfo = found_binfo;
|
||||
else
|
||||
binfo = lookup_binfo_at_offset (binfo, TREE_TYPE (fld), offset);
|
||||
}
|
||||
|
||||
type = TREE_TYPE (fld);
|
||||
offset -= pos;
|
||||
|
|
Loading…
Reference in New Issue