From: Jason Merrill Date: Wed, 12 Nov 1997 09:19:26 +0000 (+0000) Subject: init.c (build_new): Handle freeing allocated memory when the constructor throws. X-Git-Tag: releases/egcs-1.0.0~140 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e18138c8f78720ae655c48a77919fb4b36691640;p=thirdparty%2Fgcc.git init.c (build_new): Handle freeing allocated memory when the constructor throws. * init.c (build_new): Handle freeing allocated memory when the constructor throws. * call.c (build_new_method_call): Fix flags arg. * pt.c (do_type_instantiation): Don't try to instantiate member templates. (mark_decl_instantiated): If we support one_only but not weak symbols, mark this one_only. * decl2.c (import_export_vtable): Don't defer handling of vtables if MULTIPLE_SYMBOL_SPACES. From-SVN: r16437 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6a56778d92c8..6971e935aaa7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +Wed Nov 12 00:48:16 1997 Jason Merrill + + * init.c (build_new): Handle freeing allocated memory when the + constructor throws. + + * call.c (build_new_method_call): Fix flags arg. + + * pt.c (do_type_instantiation): Don't try to instantiate + member templates. + (mark_decl_instantiated): If we support one_only but not + weak symbols, mark this one_only. + * decl2.c (import_export_vtable): Don't defer handling of vtables + if MULTIPLE_SYMBOL_SPACES. + Tue Nov 11 12:02:12 1997 Jason Merrill * except.c (expand_end_catch_block): Lose call to __sjpopnthrow. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index eaa39c69e720..d4cf780f277b 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4810,9 +4810,6 @@ build_new_op (code, flags, arg1, arg2, arg3) if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) arg2 = integer_zero_node; - fns = lookup_name_nonclass (fnname); - /* + Koenig lookup */ - if (arg2 && arg3) arglist = scratch_tree_cons (NULL_TREE, arg1, scratch_tree_cons (NULL_TREE, arg2, build_scratch_list (NULL_TREE, arg3))); @@ -4821,6 +4818,9 @@ build_new_op (code, flags, arg1, arg2, arg3) else arglist = build_scratch_list (NULL_TREE, arg1); + fns = lookup_name_nonclass (fnname); + /* + Koenig lookup */ + if (fns && TREE_CODE (fns) == TREE_LIST) fns = TREE_VALUE (fns); for (; fns; fns = DECL_CHAIN (fns)) @@ -5575,8 +5575,7 @@ build_new_method_call (instance, name, args, basetype_path, flags) candidates = add_template_candidate (candidates, t, explicit_targs, this_arglist, - TREE_TYPE (name), - LOOKUP_NORMAL); + TREE_TYPE (name), flags); } else if (! template_only) candidates = add_function_candidate (candidates, t, diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index c9c7f7c0fb2b..583b7d403ad5 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2528,6 +2528,7 @@ import_export_vtable (decl, type, final) int found = CLASSTYPE_TEMPLATE_INSTANTIATION (type); +#ifndef MULTIPLE_SYMBOL_SPACES if (! found && ! final) { tree method; @@ -2541,6 +2542,7 @@ import_export_vtable (decl, type, final) break; } } +#endif if (final || ! found) { diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 09a3de18c14e..5c02d053bdd4 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2522,7 +2522,7 @@ build_new (placement, decl, init, use_global_new) TREE_CALLS_NEW (rval) = 1; } - if (check_new && rval) + if ((flag_exceptions || check_new) && rval) alloc_expr = rval = save_expr (rval); else alloc_expr = NULL_TREE; @@ -2705,13 +2705,34 @@ build_new (placement, decl, init, use_global_new) rval = xval; } #endif + + /* If any part of the object initialization terminates by throwing + an exception and the new-expression does not contain a + new-placement, then the deallocation function is called to free + the memory in which the object was being constructed. */ + /* FIXME: handle placement delete. */ + if (flag_exceptions && ! placement) + { + tree cleanup; + + if (! use_global_new && TYPE_LANG_SPECIFIC (true_type) + && (TYPE_GETS_DELETE (true_type) & (1 << has_array))) + cleanup = build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, + alloc_expr, size, NULL_TREE); + else + cleanup = build_builtin_call + (void_type_node, BID, build_expr_list (NULL_TREE, alloc_expr)); + + rval = build (TRY_CATCH_EXPR, TREE_TYPE (rval), rval, cleanup); + rval = build (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval); + } } else if (TYPE_READONLY (true_type)) cp_error ("uninitialized const in `new' of `%#T'", true_type); done: - if (alloc_expr && rval != alloc_expr) + if (check_new && alloc_expr && rval != alloc_expr) { /* Did we modify the storage? */ tree ifexp = build_binary_op (NE_EXPR, alloc_expr, diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 1d16bb2de0ef..96b21aae03b4 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3962,6 +3962,8 @@ mark_decl_instantiated (result, extern_p) { DECL_INTERFACE_KNOWN (result) = 1; DECL_NOT_REALLY_EXTERN (result) = 1; + if (supports_one_only () && ! SUPPORTS_WEAK) + comdat_linkage (result); } else if (TREE_CODE (result) == FUNCTION_DECL) mark_inline_for_output (result); @@ -4371,7 +4373,8 @@ do_type_instantiation (t, storage) if (! static_p) for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp)) - if (DECL_TEMPLATE_INSTANTIATION (tmp)) + if (TREE_CODE (t) == FUNCTION_DECL + && DECL_TEMPLATE_INSTANTIATION (tmp)) { mark_decl_instantiated (tmp, extern_p); repo_template_instantiated (tmp, extern_p);