OSDN Git Service

cp:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 12 Apr 2001 07:44:48 +0000 (07:44 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 12 Apr 2001 07:44:48 +0000 (07:44 +0000)
* class.c (dfs_unshared_virtual_bases): New function.
(mark_primary_bases): Call it.
(check_bases): Ignore virtual bases when determining
nearly-emptiness.
testsuite:
* g++.old-deja/g++.abi/primary3.C (main): Correct expected layout.
* g++.old-deja/g++.abi/crash1.C: New test.

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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.abi/crash1.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.abi/primary3.C

index 1066de1..634c8cf 100644 (file)
@@ -1,5 +1,12 @@
 2001-04-12  Nathan Sidwell  <nathan@codesourcery.com>
 
+       * class.c (dfs_unshared_virtual_bases): New function.
+       (mark_primary_bases): Call it.
+       (check_bases): Ignore virtual bases when determining
+       nearly-emptiness.
+
+2001-04-12  Nathan Sidwell  <nathan@codesourcery.com>
+
        * method.c (make_thunk): Clear DECL_CLONED_FUNCTION.
 
 2001-04-11  Mark Mitchell  <mark@codesourcery.com>
index 406843e..290dc21 100644 (file)
@@ -190,6 +190,7 @@ static void build_vcall_and_vbase_vtbl_entries PARAMS ((tree,
                                                        vtbl_init_data *));
 static void force_canonical_binfo_r PARAMS ((tree, tree, tree, tree));
 static void force_canonical_binfo PARAMS ((tree, tree, tree, tree));
+static tree dfs_unshared_virtual_bases PARAMS ((tree, void *));
 static void mark_primary_bases PARAMS ((tree));
 static tree mark_primary_virtual_base PARAMS ((tree, tree, tree));
 static void clone_constructors_and_destructors PARAMS ((tree));
@@ -1596,12 +1597,12 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
 {
   int n_baseclasses;
   int i;
-  int seen_nearly_empty_base_p;
+  int seen_non_virtual_nearly_empty_base_p;
   tree binfos;
 
   binfos = TYPE_BINFO_BASETYPES (t);
   n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
-  seen_nearly_empty_base_p = 0;
+  seen_non_virtual_nearly_empty_base_p = 0;
 
   /* An aggregate cannot have baseclasses.  */
   CLASSTYPE_NON_AGGREGATE (t) |= (n_baseclasses != 0);
@@ -1662,19 +1663,23 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
                         basetype);
        }
 
-      /* If the base class is not empty or nearly empty, then this
-        class cannot be nearly empty.  */
-      if (!CLASSTYPE_NEARLY_EMPTY_P (basetype) && !is_empty_class (basetype))
-       CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
-      /* And if there is more than one nearly empty base, then the
-        derived class is not nearly empty either.  */
-      else if (CLASSTYPE_NEARLY_EMPTY_P (basetype) 
-              && seen_nearly_empty_base_p)
-       CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
-      /* If this is the first nearly empty base class, then remember
-        that we saw it.  */
+      if (TREE_VIA_VIRTUAL (base_binfo))
+       /* A virtual base does not effect nearly emptiness. */
+       ;
       else if (CLASSTYPE_NEARLY_EMPTY_P (basetype))
-       seen_nearly_empty_base_p = 1;
+       {
+         if (seen_non_virtual_nearly_empty_base_p)
+           /* And if there is more than one nearly empty base, then the
+              derived class is not nearly empty either.  */
+           CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+         else
+           /* Remember we've seen one. */
+           seen_non_virtual_nearly_empty_base_p = 1;
+       }
+      else if (!is_empty_class (basetype))
+       /* If the base class is not empty or nearly empty, then this
+          class cannot be nearly empty.  */
+       CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
 
       /* A lot of properties from the bases also apply to the derived
         class.  */
@@ -1814,6 +1819,23 @@ mark_primary_virtual_base (binfo, base_binfo, type)
   return base_binfo;
 }
 
+/* If BINFO is an unmarked virtual binfo for a class with a primary
+   base, then BINFO has no primary base in this graph.  Called from
+   mark_primary_bases. */
+
+static tree dfs_unshared_virtual_bases (binfo, data)
+     tree binfo;
+     void *data;
+{
+  if (TREE_VIA_VIRTUAL (binfo) && !BINFO_MARKED (binfo)
+      && CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
+    BINFO_LOST_PRIMARY_P (binfo) = 1;
+
+  CLEAR_BINFO_MARKED (binfo);
+  
+  return NULL;
+}
+
 /* Set BINFO_PRIMARY_BASE_OF for all binfos in the hierarchy
    dominated by TYPE that are primary bases.  */
 
@@ -1839,7 +1861,12 @@ mark_primary_bases (type)
 
       if (base_binfo)
         BINFO_PRIMARY_BASE_OF (base_binfo) = binfo;
+      SET_BINFO_MARKED (binfo);
     }
+  /* There could remain unshared virtual bases which were not visited
+     in the inheritance graph walk. These bases will have lost their
+     primary base (should they have one). We must now find them. */
+  dfs_walk (TYPE_BINFO (type), dfs_unshared_virtual_bases, NULL, NULL);
 }
 
 /* Make the BINFO the primary base of T.  */
index 36c2e53..ea72f12 100644 (file)
@@ -1,4 +1,9 @@
 2001-04-12  Nathan Sidwell  <nathan@codesourcery.com>
+       
+       * g++.old-deja/g++.abi/primary3.C (main): Correct expected layout.
+       * g++.old-deja/g++.abi/crash1.C: New test.
+
+2001-04-12  Nathan Sidwell  <nathan@codesourcery.com>
 
        * g++.old-deja/g++.other/crash40.C: New test.
 
diff --git a/gcc/testsuite/g++.old-deja/g++.abi/crash1.C b/gcc/testsuite/g++.old-deja/g++.abi/crash1.C
new file mode 100644 (file)
index 0000000..8526818
--- /dev/null
@@ -0,0 +1,21 @@
+// Build don't link:
+// 
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 11 Apr 2001 <nathan@codesourcery.com>
+
+// Bug 1944. We failed to calculate nearly emptiness properly, and
+// lost primary too.
+
+struct A1 {};
+struct A2 {};
+
+struct B1 : virtual A1 {};
+struct B2 : virtual A2 {};
+
+struct C1 : virtual B2 {};
+struct C2 : virtual B2 {};
+
+struct D1 : virtual C1, virtual C2 {};
+struct D2 : virtual C2, virtual B1 {};
+
+struct E : virtual D1, virtual D2 {};
index ef245ef..fbeb2b7 100644 (file)
@@ -21,14 +21,24 @@ int main ()
   A *apd = &d;
   B1 *b1pd = &d;
   B2 *b2pd = &d;
+  C *cpd = &d;
   
 #if __GXX_ABI_VERSION >= 100
   if (static_cast <void *> (apc) != static_cast <void *> (b1pc))
     return 1;
-  if (static_cast <void *> (apd) != static_cast <void *> (b1pd))
+  if (static_cast <void *> (&c) != static_cast <void *> (b2pc))
     return 2;
-  if (static_cast <void *> (apd) != static_cast <void *> (&d))
+  if (static_cast <void *> (b1pc) == static_cast <void *> (b2pc))
     return 3;
+  
+  if (static_cast <void *> (apd) != static_cast <void *> (b1pd))
+    return 11;
+  if (static_cast <void *> (b2pd) != static_cast <void *> (&d))
+    return 12;
+  if (static_cast <void *> (b2pd) != static_cast <void *> (cpd))
+    return 13;
+  if (static_cast <void *> (b1pd) == static_cast <void *> (b2pd))
+    return 14;
 #endif
   return 0;
 }