re PR ipa/60871 (internal compiler error: in possible_polymorphic_call_targets, at...
authorJan Hubicka <hubicka@ucw.cz>
Tue, 27 Jan 2015 19:39:37 +0000 (20:39 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 27 Jan 2015 19:39:37 +0000 (19:39 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr60871.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/pr64139.C [new file with mode: 0644]
gcc/tree.c

index 03097cf2a3fbb39aa69bbaad76385cc9a9451025..36d0045f1943f7e8f4f3207682ab7d1430fc6308 100644 (file)
@@ -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
index 8b1e05085ffdbce28f6ca95b010affd8821b95ec..8d50aacf55ddd415eb6aa04fa3d31232f4a28ce9 100644 (file)
@@ -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
diff --git a/gcc/testsuite/g++.dg/torture/pr60871.C b/gcc/testsuite/g++.dg/torture/pr60871.C
new file mode 100644 (file)
index 0000000..902b9ee
--- /dev/null
@@ -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 (); }
diff --git a/gcc/testsuite/g++.dg/torture/pr64139.C b/gcc/testsuite/g++.dg/torture/pr64139.C
new file mode 100644 (file)
index 0000000..932a676
--- /dev/null
@@ -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);
+}
+
index e1d069d8dc06e539ad4df3f775e5ce107ea13521..6fe1d5a0d55379dfb263fc65191b02fe8f35a4de 100644 (file)
@@ -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;