From f2ec1f0a57f17be0476eb822537f5277fa91d970 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 21 Oct 2002 09:29:12 +0000 Subject: [PATCH] re PR c++/8218 (Excessively large amount of memory used with classes with large array members) 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 | 11 +++++++++++ gcc/cp/class.c | 25 +++++++++++++++++++++++++ gcc/cp/cp-tree.h | 7 ++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3353d79e8d70..8739a34bd07b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2002-10-21 Mark Mitchell + + 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 * decl.c (start_decl): Point users of the old initialized- diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 6bb1e4e945cd..1c8ff2b26688 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 43a9817d7836..65ef4daa7cfb 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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. */ -- 2.47.2