diff options
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r-- | gcc/cp/class.c | 86 |
1 files changed, 59 insertions, 27 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 2ec3448..c3aa297 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -218,6 +218,7 @@ static int layout_conflict_p PARAMS ((tree, tree, splay_tree, int)); static int splay_tree_compare_integer_csts PARAMS ((splay_tree_key k1, splay_tree_key k2)); static void warn_about_ambiguous_direct_bases PARAMS ((tree)); +static bool type_requires_array_cookie PARAMS ((tree)); /* Macros for dfs walking during vtt construction. See dfs_ctor_vtable_bases_queue_p, dfs_build_secondary_vptr_vtt_inits @@ -4210,7 +4211,6 @@ check_methods (t) tree t; { tree x; - int seen_one_arg_array_delete_p = 0; for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) { @@ -4234,32 +4234,6 @@ check_methods (t) CLASSTYPE_PURE_VIRTUALS (t) = tree_cons (NULL_TREE, x, CLASSTYPE_PURE_VIRTUALS (t)); } - - if (DECL_ARRAY_DELETE_OPERATOR_P (x)) - { - tree second_parm; - - /* When dynamically allocating an array of this type, we - need a "cookie" to record how many elements we allocated, - even if the array elements have no non-trivial - destructor, if the usual array deallocation function - takes a second argument of type size_t. The standard (in - [class.free]) requires that the second argument be set - correctly. */ - second_parm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (x))); - /* Under the new ABI, we choose only those function that are - explicitly declared as `operator delete[] (void *, - size_t)'. */ - if (!seen_one_arg_array_delete_p - && second_parm - && TREE_CHAIN (second_parm) == void_list_node - && same_type_p (TREE_VALUE (second_parm), sizetype)) - TYPE_VEC_DELETE_TAKES_SIZE (t) = 1; - /* If there's no second parameter, then this is the usual - deallocation function. */ - else if (second_parm == void_list_node) - seen_one_arg_array_delete_p = 1; - } } } @@ -4556,6 +4530,59 @@ remove_zero_width_bit_fields (t) } } +/* Returns TRUE iff we need a cookie when dynamically allocating an + array whose elements have the indicated class TYPE. */ + +static bool +type_requires_array_cookie (type) + tree type; +{ + tree fns; + bool has_two_argument_delete_p; + + my_friendly_assert (CLASS_TYPE_P (type), 20010712); + + /* If there's a non-trivial destructor, we need a cookie. In order + to iterate through the array calling the destructor for each + element, we'll have to know how many elements there are. */ + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) + return true; + + /* If the usual deallocation function is a two-argument whose second + argument is of type `size_t', then we have to pass the size of + the array to the deallocation function, so we will need to store + a cookie. */ + fns = lookup_fnfields (TYPE_BINFO (type), + ansi_opname (VEC_DELETE_EXPR), + /*protect=*/0); + /* If there are no `operator []' members, or the lookup is + ambiguous, then we don't need a cookie. */ + if (!fns || fns == error_mark_node) + return false; + /* Loop through all of the functions. */ + for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns)) + { + tree fn; + tree second_parm; + + /* Select the current function. */ + fn = OVL_CURRENT (fns); + /* See if this function is a one-argument delete function. If + it is, then it will be the usual deallocation function. */ + second_parm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn))); + if (second_parm == void_list_node) + return false; + /* Otherwise, if we have a two-argument function and the second + argument is `size_t', it will be the usual deallocation + function -- unless there is one-argument function, too. */ + if (TREE_CHAIN (second_parm) == void_list_node + && same_type_p (TREE_VALUE (second_parm), sizetype)) + has_two_argument_delete_p = true; + } + + return has_two_argument_delete_p; +} + /* Check the validity of the bases and members declared in T. Add any implicitly-generated functions (like copy-constructors and assignment operators). Compute various flag bits (like @@ -4641,6 +4668,11 @@ check_bases_and_members (t, empty_p) /* Build and sort the CLASSTYPE_METHOD_VEC. */ finish_struct_methods (t); + + /* Figure out whether or not we will need a cookie when dynamically + allocating an array of this type. */ + TYPE_LANG_SPECIFIC (t)->vec_new_uses_cookie + = type_requires_array_cookie (t); } /* If T needs a pointer to its virtual function table, set TYPE_VFIELD |