]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/21427 ([3.4/4.0 only] Failure in make_thunk, cp/method.c:145 when compiling...
authorNathan Sidwell <nathan@codesourcery.com>
Mon, 9 May 2005 11:48:11 +0000 (11:48 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Mon, 9 May 2005 11:48:11 +0000 (11:48 +0000)
cp:
PR c++/21427
Backport 2005-03-01  Nathan Sidwell  <nathan@codesourcery.com>
* class.c (update_vtable_entry_for_fn): Don't crash on invalid
covariancy.

* cp-tree.h (THUNK_TARGET): Expand comment.
* method.c (use_thunk): Make sure we also use the target, if that
is a thunk.

Backport 2005-02-11  Nathan Sidwell  <nathan@codesourcery.com>
* class.c (update_vtable_entry_for_fn): Walk the covariant's binfo
chain rather than using lookup_base.
testsuite:
PR c++/21427
* g++.dg/inherit/covariant13.C: New.
Backport 2005-03-01  Nathan Sidwell  <nathan@codesourcery.com>
* g++.dg/inherit/covariant12.C: New.

From-SVN: r99430

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/method.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/inherit/covariant13.C [new file with mode: 0644]

index bd59b7acfe176fbe1a929afb33d359967a173b3a..9f5dbf286bbf1e30dd963c990e90cc6460ef7678 100644 (file)
@@ -1,3 +1,18 @@
+2005-05-08  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/21427
+       Backport 2005-03-01  Nathan Sidwell  <nathan@codesourcery.com>
+       * class.c (update_vtable_entry_for_fn): Don't crash on invalid
+       covariancy. 
+
+       * cp-tree.h (THUNK_TARGET): Expand comment.
+       * method.c (use_thunk): Make sure we also use the target, if that
+       is a thunk.
+
+       Backport 2005-02-11  Nathan Sidwell  <nathan@codesourcery.com>
+       * class.c (update_vtable_entry_for_fn): Walk the covariant's binfo
+       chain rather than using lookup_base.
+
 2005-05-04  Mark Mitchell  <mark@codesourcery.com>
 
        Backport:
index a7093b174c3ec33214442462f64127b4abb718b0..09daf118a80f9e50b090185f851ff7b34761182d 100644 (file)
@@ -2116,6 +2116,9 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
          also be converting to the return type of FN, we have to
          combine the two conversions here.  */
       tree fixed_offset, virtual_offset;
+
+      over_return = TREE_TYPE (over_return);
+      base_return = TREE_TYPE (base_return);
       
       if (DECL_THUNK_P (fn))
        {
@@ -2133,32 +2136,51 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
        virtual_offset =
          TREE_VALUE (purpose_member
                      (BINFO_TYPE (virtual_offset),
-                      CLASSTYPE_VBASECLASSES (TREE_TYPE (over_return))));
-      else if (!same_type_p (TREE_TYPE (over_return),
-                            TREE_TYPE (base_return)))
+                      CLASSTYPE_VBASECLASSES (over_return)));
+      else if (!same_type_ignoring_top_level_qualifiers_p
+              (over_return, base_return))
        {
-         /* There was no existing virtual thunk (which takes
-            precedence).  */
-         tree thunk_binfo;
-         base_kind kind;
+         /* 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
+            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
+            search here anyway -- we should really be caching pieces
+            of the vtable and avoiding this repeated work.  */
+         tree thunk_binfo, base_binfo;
+
+         /* Find the base binfo within the overriding function's
+            return type.  We will always find a thunk_binfo, except
+            when the covariancy is invalid (which we will have
+            already diagnosed).  */
+         for (base_binfo = TYPE_BINFO (base_return),
+              thunk_binfo = TYPE_BINFO (over_return);
+              thunk_binfo;
+              thunk_binfo = TREE_CHAIN (thunk_binfo))
+           if (same_type_p (BINFO_TYPE (thunk_binfo),
+                            BINFO_TYPE (base_binfo)))
+             break;
          
-         thunk_binfo = lookup_base (TREE_TYPE (over_return),
-                                    TREE_TYPE (base_return),
-                                    ba_check | ba_quiet, &kind);
-
-         if (thunk_binfo && (kind == bk_via_virtual
-                             || !BINFO_OFFSET_ZEROP (thunk_binfo)))
+         /* See if virtual inheritance is involved.  */
+         for (virtual_offset = thunk_binfo;
+              virtual_offset;
+              virtual_offset = BINFO_INHERITANCE_CHAIN (virtual_offset))
+           if (TREE_VIA_VIRTUAL (virtual_offset))
+             break;
+         
+         if (virtual_offset
+             || (thunk_binfo && !BINFO_OFFSET_ZEROP (thunk_binfo)))
            {
              tree offset = convert (ssizetype, BINFO_OFFSET (thunk_binfo));
 
-             if (kind == bk_via_virtual)
+             if (virtual_offset)
                {
-                 /* We convert via virtual base. Find the virtual
-                    base and adjust the fixed offset to be from there.  */
-                 while (!TREE_VIA_VIRTUAL (thunk_binfo))
-                   thunk_binfo = BINFO_INHERITANCE_CHAIN (thunk_binfo);
-
-                 virtual_offset = thunk_binfo;
+                 /* We convert via virtual base.  Adjust the fixed
+                    offset to be from there.  */
                  offset = size_diffop
                    (offset, convert
                     (ssizetype, BINFO_OFFSET (virtual_offset)));
index 9bf76bc008ff736eeeb56abb192b4b32784be707..ed33f3271d7985ca8939db91ca7baf943407f249 100644 (file)
@@ -2917,7 +2917,8 @@ struct lang_decl GTY(())
 #define THUNK_ALIAS(DECL) \
   (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.u.thunk_alias)
 
-/* For thunk NODE, this is the FUNCTION_DECL thunked to.  */
+/* For thunk NODE, this is the FUNCTION_DECL thunked to.  It is
+   possible for the target to be a thunk too.  */
 #define THUNK_TARGET(NODE)                             \
   (DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes)
 
index 42e50926f2673587a105906da7ee9163fbb30546..ef69c37fe4d7f8b26f5150dfd53e9420717ed432 100644 (file)
@@ -357,6 +357,10 @@ use_thunk (tree thunk_fndecl, bool emit_p)
        There's no need to process this thunk again.  */
     return;
 
+  if (DECL_THUNK_P (function))
+    /* The target is itself a thunk, process it now.  */
+    use_thunk (function, emit_p);
+  
   /* Thunks are always addressable; they only appear in vtables.  */
   TREE_ADDRESSABLE (thunk_fndecl) = 1;
 
index 6be57523a1b7ff2bf9834beb2da36c8c72cd84e8..1ee2e6f363872ceecbf58dfd5ff78132105af652 100644 (file)
@@ -1,3 +1,10 @@
+2005-05-08  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/21427
+       * g++.dg/inherit/covariant13.C: New.
+       Backport 2005-03-01  Nathan Sidwell  <nathan@codesourcery.com>
+       * g++.dg/inherit/covariant12.C: New.
+
 2005-05-04  Mark Mitchell  <mark@codesourcery.com>
 
        Backport:
diff --git a/gcc/testsuite/g++.dg/inherit/covariant13.C b/gcc/testsuite/g++.dg/inherit/covariant13.C
new file mode 100644 (file)
index 0000000..af60840
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright (C) 2004 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 8 May 2005<nathan@codesourcery.com>
+
+// Origin:Andrew Pinski: pinskia@gcc.gnu.org
+// PR 21427: ICE on valid
+
+struct B1 { 
+  public: 
+    virtual void foo(); 
+}; 
+struct B2 { 
+  public: 
+    virtual B2 & bar() = 0; 
+}; 
+struct I : public B1, B2 { 
+  public: 
+    virtual ~I(); 
+    virtual I & bar(); 
+}; 
+struct D : public I { 
+    virtual ~D(); 
+};