]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/8218 (Excessively large amount of memory used with classes with large array...
authorMark Mitchell <mark@codesourcery.com>
Mon, 21 Oct 2002 09:29:12 +0000 (09:29 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Mon, 21 Oct 2002 09:29:12 +0000 (09:29 +0000)
PR c++/8218
* cp-tree.h (lang_type_class): Add contains_empty_class_p.
(CLASSTYPE_CONTAINS_EMPTY_CLASS_P): New macro.
* class.c (check_bases): Update CLASSTYPE_CONTAINS_EMPTY_CLASS_P.
(check_field_decls): Likewise.
(layout_class_type): Likewise.
(finish_struct_1): Initialize it.
(walk_subobject_offsets): Use it to prune searches.

From-SVN: r58357

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h

index 3353d79e8d70d211e893bf4bca0a5f7ea2759fb8..8739a34bd07b5934f91c17441f65854f90884523 100644 (file)
@@ -1,3 +1,14 @@
+2002-10-21  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/8218
+       * cp-tree.h (lang_type_class): Add contains_empty_class_p.
+       (CLASSTYPE_CONTAINS_EMPTY_CLASS_P): New macro.
+       * class.c (check_bases): Update CLASSTYPE_CONTAINS_EMPTY_CLASS_P.
+       (check_field_decls): Likewise.
+       (layout_class_type): Likewise.
+       (finish_struct_1): Initialize it.
+       (walk_subobject_offsets): Use it to prune searches.
+
 2002-10-18  Zack Weinberg  <zack@codesourcery.com>
 
        * decl.c (start_decl): Point users of the old initialized-
index 6bb1e4e945cd17545108b673423bc16ffe6ef775..1c8ff2b26688fb465ce9f82dcaa8532247b33714 100644 (file)
@@ -1348,6 +1348,8 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
       TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype);
       TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype);
       TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype);
+      CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) 
+       |= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
     }
 }
 
@@ -3247,10 +3249,18 @@ check_field_decls (t, access_decls, empty_p,
            ;
          else
            {
+             tree element_type;
+
              /* The class is non-empty.  */
              *empty_p = 0;
              /* The class is not even nearly empty.  */
              CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+             /* If one of the data members contains an empty class,
+                so does T.  */
+             element_type = strip_array_types (type);
+             if (CLASS_TYPE_P (element_type) 
+                 && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type))
+               CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type) = 1;
            }
        }
 
@@ -3517,6 +3527,10 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p)
       tree field;
       int i;
 
+      /* Avoid recursing into objects that are not interesting.  */
+      if (!CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
+       return 0;
+
       /* Record the location of TYPE.  */
       r = (*f) (type, offset, offsets);
       if (r)
@@ -3562,9 +3576,15 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p)
     }
   else if (TREE_CODE (type) == ARRAY_TYPE)
     {
+      tree element_type = strip_array_types (type);
       tree domain = TYPE_DOMAIN (type);
       tree index;
 
+      /* Avoid recursing into objects that are not interesting.  */
+      if (!CLASS_TYPE_P (element_type)
+         || !CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type))
+       return 0;
+
       /* Step through each of the elements in the array.  */
       for (index = size_zero_node; 
           INT_CST_LT (index, TYPE_MAX_VALUE (domain));
@@ -4277,6 +4297,7 @@ check_bases_and_members (t, empty_p)
   /* Assume that the class is nearly empty; we'll clear this flag if
      it turns out not to be nearly empty.  */
   CLASSTYPE_NEARLY_EMPTY_P (t) = 1;
+  CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0;
 
   /* Check all the base-classes. */
   check_bases (t, &cant_have_default_ctor, &cant_have_const_ctor,
@@ -4984,6 +5005,10 @@ layout_class_type (t, empty_p, vfuns_p, virtuals_p)
   CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t);
   CLASSTYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (t);
 
+  /* Every empty class contains an empty class.  */
+  if (*empty_p)
+    CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
+
   /* Set the TYPE_DECL for this type to contain the right
      value for DECL_OFFSET, so that we can use it as part
      of a COMPONENT_REF for multiple inheritance.  */
index 43a9817d78362275f1c96bafffab6372a1b6abbf..65ef4daa7cfb104f3dffe04d26b6d3f557fa4a62 100644 (file)
@@ -1251,6 +1251,7 @@ struct lang_type
   unsigned java_interface : 1;
 
   unsigned non_zero_init : 1;
+  unsigned contains_empty_class_p : 1;
 
   /* When adding a flag here, consider whether or not it ought to
      apply to a template instance if it applies to the template.  If
@@ -1259,7 +1260,7 @@ struct lang_type
   /* There are some bits left to fill out a 32-bit word.  Keep track
      of this by updating the size of this bitfield whenever you add or
      remove a flag.  */
-  unsigned dummy : 7;
+  unsigned dummy : 6;
 
   int vsize;
 
@@ -1520,6 +1521,10 @@ struct lang_type
 #define CLASSTYPE_NEARLY_EMPTY_P(NODE) \
   (TYPE_LANG_SPECIFIC (NODE)->nearly_empty_p)
 
+/* Nonzero if this class contains an empty subobject.  */
+#define CLASSTYPE_CONTAINS_EMPTY_CLASS_P(NODE) \
+  (TYPE_LANG_SPECIFIC (NODE)->contains_empty_class_p)
+
 /* A list of class types of which this type is a friend.  The
    TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the
    case of a template friend.  */