]> gcc.gnu.org Git - gcc.git/commitdiff
re PR ipa/59775 (internal compiler error: Segmentation fault)
authorJan Hubicka <jh@suse.cz>
Fri, 17 Jan 2014 01:04:59 +0000 (02:04 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 17 Jan 2014 01:04:59 +0000 (01:04 +0000)
PR ipa/59775
* tree.c (get_binfo_at_offset): Look harder for virtual bases.

From-SVN: r206694

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

index e07d1aeefe7de9f91251bd2c3f0fbc68b093af20..5a575e01303e8986afc4ece106ada0b4e2e03e54 100644 (file)
@@ -1,3 +1,8 @@
+2014-01-16  Jan Hubicka  <jh@suse.cz>
+
+       PR ipa/59775
+       * tree.c (get_binfo_at_offset): Look harder for virtual bases.
+
 2014-01-16  Bernd Schmidt  <bernds@codesourcery.com>
 
        PR middle-end/56791
index fa17276b77aa3e8c516f26f53deec84b8d591483..a85acbeac849bb1d42b0c5786d7d661fce4b03af 100644 (file)
@@ -1,3 +1,8 @@
+2014-01-16  Jan Hubicka  <jh@suse.cz>
+
+       PR ipa/59775
+       * g++.dg/torture/pr59775.C: New testcase.
+
 2014-01-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/58344
diff --git a/gcc/testsuite/g++.dg/torture/pr59775.C b/gcc/testsuite/g++.dg/torture/pr59775.C
new file mode 100644 (file)
index 0000000..10c4975
--- /dev/null
@@ -0,0 +1,21 @@
+// { dg-do compile }
+struct A
+{
+  virtual void foo () = 0;
+  void bar () { foo (); }
+  bool a;
+};
+struct B : public virtual A
+{
+  virtual void foo ();
+};
+struct C : public B
+{
+  C ();
+};
+void
+baz ()
+{
+  C c;
+  c.bar ();
+}
index 37a7ed4b3a0bdc9200049b1090b1f1a09ac78835..76e3efb4920d1b17e0033090313066caac6c8582 100644 (file)
@@ -11995,16 +11995,35 @@ 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, found_binfo = NULL_TREE;
-         for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
-           if (types_same_for_odr (TREE_TYPE (base_binfo), TREE_TYPE (fld)))
-             {
-               found_binfo = base_binfo;
-               break;
-             }
-         if (!found_binfo)
-           return NULL_TREE;
-         binfo = found_binfo;
+         tree base_binfo, binfo2 = binfo;
+
+         /* 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 (BINFO_OFFSET (base_binfo) - BINFO_OFFSET (binfo) < pos
+                     && (!containing_binfo
+                         || (BINFO_OFFSET (containing_binfo)
+                             < BINFO_OFFSET (base_binfo))))
+                   containing_binfo = base_binfo;
+             if (found_binfo)
+               {
+                 binfo = found_binfo;
+                 break;
+               }
+             if (!containing_binfo)
+               return NULL_TREE;
+             binfo2 = containing_binfo;
+           }
        }
 
       type = TREE_TYPE (fld);
This page took 0.081855 seconds and 5 git commands to generate.