From 5ec1192eb5b091bb0822591b5371fd0f9ba70946 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 21 Oct 2002 08:40:24 +0000 Subject: 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: r58356 --- gcc/cp/ChangeLog | 11 +++++++++++ gcc/cp/class.c | 29 +++++++++++++++++++++++++++-- gcc/cp/cp-tree.h | 7 ++++++- 3 files changed, 44 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bbe1ae8..350b016 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-20 Mark Mitchell * method.c (use_thunk): Compute the vcall index as a HOST_WIDE_INT. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 7afe273..1745c0d 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1352,6 +1352,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); } } @@ -3167,10 +3169,18 @@ check_field_decls (tree t, tree *access_decls, ; else { + tree element_type; + /* The class is non-empty. */ CLASSTYPE_EMPTY_P (t) = 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; } } @@ -3440,6 +3450,10 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p) tree binfo; 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) @@ -3523,9 +3537,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; /* G++ 3.2 had an off-by-one error here. */ @@ -4988,6 +5008,10 @@ layout_class_type (tree t, int *vfuns_p, tree *virtuals_p) else CLASSTYPE_AS_BASE (t) = t; + /* Every empty class contains an empty class. */ + if (CLASSTYPE_EMPTY_P (t)) + 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. */ @@ -5076,10 +5100,11 @@ finish_struct_1 (t) fixup_inline_methods (t); - /* Assume that the class is both empty and nearly empty; we'll clear - these flag if necessary. */ + /* Make assumptions about the class; we'll reset the flags if + necessary. */ CLASSTYPE_EMPTY_P (t) = 1; CLASSTYPE_NEARLY_EMPTY_P (t) = 1; + CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0; /* Do end-of-class semantic processing: checking the validity of the bases and members and add implicitly generated methods. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 52f921c..06e80b5 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1135,6 +1135,7 @@ struct lang_type_class GTY(()) unsigned anon_aggr : 1; unsigned non_zero_init : 1; unsigned empty_p : 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 @@ -1143,7 +1144,7 @@ struct lang_type_class GTY(()) /* 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 : 5; + unsigned dummy : 4; int vsize; @@ -1457,6 +1458,10 @@ struct lang_type GTY(()) #define CLASSTYPE_NEARLY_EMPTY_P(NODE) \ (LANG_TYPE_CLASS_CHECK (NODE)->nearly_empty_p) +/* Nonzero if this class contains an empty subobject. */ +#define CLASSTYPE_CONTAINS_EMPTY_CLASS_P(NODE) \ + (LANG_TYPE_CLASS_CHECK (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. */ -- cgit v1.1