OSDN Git Service

PR c++/12881
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 12 Dec 2003 14:06:53 +0000 (14:06 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 12 Dec 2003 14:06:53 +0000 (14:06 +0000)
* method.c (make_thunk): Deal with thunk aliases when searching
for a thunk. Robustify assertion.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@74571 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/method.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/abi/covariant2.C [new file with mode: 0644]

index 5cad5c0..0e90958 100644 (file)
@@ -1,3 +1,9 @@
+2003-12-12  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/12881
+       * method.c (make_thunk): Deal with thunk aliases when searching
+       for a thunk. Robustify assertion.
+
 2003-12-11  Nathan Sidwell  <nathan@codesourcery.com>
 
        * mangle.c (conv_type_names): Holds IDENTIFIER_NODEs only.
index 61aebd4..a08ae6b 100644 (file)
@@ -124,20 +124,61 @@ make_thunk (tree function, bool this_adjusting,
      thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it
      will be a BINFO.  */
   for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk))
-    if (DECL_THIS_THUNK_P (thunk) == this_adjusting
-       && THUNK_FIXED_OFFSET (thunk) == d
-       && (this_adjusting
-           ? (!THUNK_VIRTUAL_OFFSET (thunk) == !virtual_offset
-              && (!virtual_offset
-                  || tree_int_cst_equal (THUNK_VIRTUAL_OFFSET (thunk), 
-                                         virtual_offset)))
-           : THUNK_VIRTUAL_OFFSET (thunk) == virtual_offset))
-      return thunk;
+    {
+      if (DECL_THIS_THUNK_P (thunk) != this_adjusting
+         || THUNK_FIXED_OFFSET (thunk) != d)
+       /*not me*/;
+      else if (this_adjusting)
+       {
+         if (!virtual_offset)
+           {
+             /* We want a non-virtual covariant thunk.  */
+             if (!THUNK_VIRTUAL_OFFSET (thunk))
+               return thunk;
+           }
+         else if (THUNK_VIRTUAL_OFFSET (thunk))
+           {
+             if (tree_int_cst_equal (THUNK_VIRTUAL_OFFSET (thunk),
+                                     virtual_offset))
+               return thunk;
+           }
+       }
+      else
+       {
+         if (!virtual_offset)
+           {
+             /* We want a non-virtual covariant thunk.  */
+             if (!THUNK_VIRTUAL_OFFSET (thunk))
+               return thunk;
+           }
+         else if (!THUNK_VIRTUAL_OFFSET (thunk))
+           /*not me*/;
+         else if (THUNK_ALIAS_P (thunk))
+           {
+             /* We have already determined the thunks for FUNCTION,
+                and there is a virtual covariant thunk alias.  We
+                must compare the vbase offsets of the binfo we have
+                been given, and the binfo of the thunk.  */
+             tree binfo = THUNK_VIRTUAL_OFFSET (THUNK_ALIAS (thunk));
+             
+             if (tree_int_cst_equal (BINFO_VPTR_FIELD (virtual_offset),
+                                     BINFO_VPTR_FIELD (binfo)))
+               return THUNK_ALIAS (thunk);
+           }
+         else if (THUNK_VIRTUAL_OFFSET (thunk) == virtual_offset)
+           return thunk;
+       }
+    }
   
   /* All thunks must be created before FUNCTION is actually emitted;
      the ABI requires that all thunks be emitted together with the
      function to which they transfer control.  */
   my_friendly_assert (!TREE_ASM_WRITTEN (function), 20021025);
+  /* Likewise, we can only be adding thunks to a function declared in
+     the class currently being laid out.  */
+  my_friendly_assert (TYPE_SIZE (DECL_CONTEXT (function))
+                     && TYPE_BEING_DEFINED (DECL_CONTEXT (function)),
+                     20031211);
 
   thunk = build_decl (FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
   DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
index 358b093..eee3f58 100644 (file)
@@ -1,3 +1,8 @@
+2003-12-12  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/12881
+       * g++.dg/abi/covariant2.C: New.
+
 2003-12-12  Neil Booth  <neil@daikokuya.co.uk>
 
        * testsuite/gcc.dg/cpp/trad/macro.c: New tests.
diff --git a/gcc/testsuite/g++.dg/abi/covariant2.C b/gcc/testsuite/g++.dg/abi/covariant2.C
new file mode 100644 (file)
index 0000000..233c55a
--- /dev/null
@@ -0,0 +1,32 @@
+// { dg-do compile }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 12 Dec 2003 <nathan@codesourcery.com>
+// Origin: Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+// PR c++/12881. ICE in thunk generation
+
+struct c1 {};
+
+struct c3 : virtual c1
+{
+    virtual c1* f6() {};
+    int i;
+};
+
+struct c6 : virtual c3 { };
+
+struct c7 : c3
+{
+    virtual c3* f6() {};
+};
+
+struct c24 : virtual c7
+{
+    virtual c6* f6();
+};
+
+c6* c24::f6() {  return 0; }
+
+struct c31 : c24 {};
+