From a0d5fba7d253e0d09de2a4f46fce6a57340407a8 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 12 Jan 1998 09:44:59 +0000 Subject: [PATCH] init.c (build_new_1): Split out from build_new. * init.c (build_new_1): Split out from build_new. (build_new): Just return a NEW_EXPR. * expr.c (cplus_expand_expr): Handle NEW_EXPR. * decl2.c (get_temp_regvar): Tweak. * cp-tree.h (TREE_CALLS_NEW): Comment out. * class.c (resolves_to_fixed_type_p): Remove use. * method.c (build_opfncall): Likewise. * call.c (build_new_op): Likewise. Fix problem with 'new' in default argument. From-SVN: r17319 --- gcc/cp/ChangeLog | 13 ++++ gcc/cp/call.c | 1 - gcc/cp/class.c | 7 -- gcc/cp/cp-tree.h | 3 + gcc/cp/decl2.c | 13 ++-- gcc/cp/expr.c | 3 + gcc/cp/init.c | 169 +++++++++++++++++------------------------------ gcc/cp/method.c | 1 - 8 files changed, 86 insertions(+), 124 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 02f3a8762c1..e4d93b14fce 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +Mon Jan 12 01:35:18 1998 Jason Merrill + + * init.c (build_new_1): Split out from build_new. + (build_new): Just return a NEW_EXPR. + * expr.c (cplus_expand_expr): Handle NEW_EXPR. + + * decl2.c (get_temp_regvar): Tweak. + + * cp-tree.h (TREE_CALLS_NEW): Comment out. + * class.c (resolves_to_fixed_type_p): Remove use. + * method.c (build_opfncall): Likewise. + * call.c (build_new_op): Likewise. + Wed Jan 7 23:47:13 1998 Jason Merrill * exception.cc (__eh_alloc, __eh_free): New fns. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index d803952dd12..848a821ee95 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4738,7 +4738,6 @@ build_new_op (code, flags, arg1, arg2, arg3) return rval; TREE_TYPE (rval) = arg1; - TREE_CALLS_NEW (rval) = 1; return rval; } diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b26979a20e7..87a0eeb0624 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4574,13 +4574,6 @@ resolves_to_fixed_type_p (instance, nonnull) return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull); case RTL_EXPR: - /* This is a call to `new', hence it's never zero. */ - if (TREE_CALLS_NEW (instance)) - { - if (nonnull) - *nonnull = 1; - return 1; - } return 0; case PLUS_EXPR: diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 79172c2cfc7..e7856f00a77 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1116,10 +1116,12 @@ struct lang_decl using a twos-complement negated operand. */ #define TREE_NEGATED_INT(NODE) (TREE_LANG_FLAG_0 (NODE)) +#if 0 /* UNUSED */ /* Nonzero in any kind of _EXPR or _REF node means that it is a call to a storage allocation routine. If, later, alternate storage is found to hold the object, this call can be ignored. */ #define TREE_CALLS_NEW(NODE) (TREE_LANG_FLAG_1 (NODE)) +#endif /* Nonzero in any kind of _TYPE that uses multiple inheritance or virtual baseclasses. */ @@ -2227,6 +2229,7 @@ extern tree build_offset_ref PROTO((tree, tree)); extern tree resolve_offset_ref PROTO((tree)); extern tree decl_constant_value PROTO((tree)); extern tree build_new PROTO((tree, tree, tree, int)); +extern tree build_new_1 PROTO((tree)); extern tree expand_vec_init PROTO((tree, tree, tree, tree, int)); extern tree build_x_delete PROTO((tree, tree, int, tree)); extern tree build_delete PROTO((tree, tree, tree, int, int)); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 71648e1c489..971a3e4d27b 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2148,21 +2148,18 @@ tree get_temp_regvar (type, init) tree type, init; { - static char buf[sizeof (AUTO_TEMP_FORMAT) + 20] = { '_' }; tree decl; - sprintf (buf+1, AUTO_TEMP_FORMAT, temp_name_counter++); - decl = build_decl (VAR_DECL, get_identifier (buf), type); + decl = build_decl (VAR_DECL, NULL_TREE, type); TREE_USED (decl) = 1; DECL_REGISTER (decl) = 1; + DECL_ARTIFICIAL (decl) = 1; - if (init) - store_init_value (decl, init); - + DECL_RTL (decl) = assign_temp (type, 2, 0, 1); /* We can expand these without fear, since they cannot need constructors or destructors. */ - expand_decl (decl); - expand_decl_init (decl); + expand_expr (build_modify_expr (decl, INIT_EXPR, init), + NULL_RTX, VOIDmode, 0); return decl; } diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index a2c166999f4..266da02e904 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -188,6 +188,9 @@ cplus_expand_expr (exp, target, tmode, modifier) integer_one_node, 1), TREE_OPERAND (exp, 1), 0), target, tmode, modifier); + case NEW_EXPR: + return expand_expr (build_new_1 (exp), target, tmode, modifier); + default: break; } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 87c8e8c785c..53cb2007f7e 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2246,12 +2246,9 @@ build_new (placement, decl, init, use_global_new) tree decl, init; int use_global_new; { - tree type, true_type, size, rval; - tree nelts; - tree alloc_expr, alloc_node; + tree type, rval; + tree nelts, t; int has_array = 0; - enum tree_code code = NEW_EXPR; - int use_cookie, nothrow, check_new; tree pending_sizes = NULL_TREE; @@ -2326,7 +2323,7 @@ build_new (placement, decl, init, use_global_new) else TREE_VALUE (decl) = absdcl; - type = true_type = groktypename (decl); + type = groktypename (decl); if (! type || type == error_mark_node) { immediate_size_expand = old_immediate_size_expand; @@ -2355,23 +2352,19 @@ build_new (placement, decl, init, use_global_new) my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 215); type = TREE_TYPE (decl); } - true_type = type; } else if (TREE_CODE (decl) == TYPE_DECL) { type = TREE_TYPE (decl); - true_type = type; } else { type = decl; - true_type = type; decl = TYPE_MAIN_DECL (type); } if (processing_template_decl) { - tree t; if (has_array) t = min_tree_cons (min_tree_cons (NULL_TREE, type, NULL_TREE), build_min_nt (ARRAY_REF, NULL_TREE, nelts), @@ -2390,7 +2383,7 @@ build_new (placement, decl, init, use_global_new) if (TREE_CODE (type) == REFERENCE_TYPE) { error ("new cannot be applied to a reference type"); - type = true_type = TREE_TYPE (type); + type = TREE_TYPE (type); } if (TREE_CODE (type) == FUNCTION_TYPE) @@ -2406,9 +2399,58 @@ build_new (placement, decl, init, use_global_new) { nelts = array_type_nelts_top (type); has_array = 1; - type = true_type = TREE_TYPE (type); + type = TREE_TYPE (type); } + if (has_array) + t = build_nt (ARRAY_REF, type, nelts); + else + t = type; + + rval = build (NEW_EXPR, build_pointer_type (type), placement, t, init); + NEW_EXPR_USE_GLOBAL (rval) = use_global_new; + TREE_SIDE_EFFECTS (rval) = 1; + + /* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain. */ + rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval); + TREE_NO_UNUSED_WARNING (rval) = 1; + + if (pending_sizes) + rval = build_compound_expr (chainon (pending_sizes, + build_expr_list (NULL_TREE, rval))); + + return rval; +} + +/* Called from cplus_expand_expr when expanding a NEW_EXPR. The return + value is immediately handed to expand_expr. */ + +tree +build_new_1 (exp) + tree exp; +{ + tree placement, init, t; + tree type, true_type, size, rval; + tree nelts; + tree alloc_expr, alloc_node; + int has_array = 0; + enum tree_code code = NEW_EXPR; + int use_cookie, nothrow, check_new; + int use_global_new; + + placement = TREE_OPERAND (exp, 0); + type = TREE_OPERAND (exp, 1); + init = TREE_OPERAND (exp, 2); + use_global_new = NEW_EXPR_USE_GLOBAL (exp); + + if (TREE_CODE (type) == ARRAY_REF) + { + has_array = 1; + nelts = TREE_OPERAND (type, 1); + type = TREE_OPERAND (type, 0); + } + true_type = type; + if (TYPE_READONLY (type) || TYPE_VOLATILE (type)) type = TYPE_MAIN_VARIANT (type); @@ -2543,21 +2585,21 @@ build_new (placement, decl, init, use_global_new) { tree extra = BI_header_size; tree cookie, exp1; - rval = cp_convert (ptr_type_node, rval); /* convert to void * first */ - rval = cp_convert (string_type_node, rval); /* lets not add void* and ints */ + rval = convert (string_type_node, rval); /* for ptr arithmetic */ rval = save_expr (build_binary_op (PLUS_EXPR, rval, extra, 1)); /* Store header info. */ - cookie = build_indirect_ref (build (MINUS_EXPR, build_pointer_type (BI_header_type), + cookie = build_indirect_ref (build (MINUS_EXPR, + build_pointer_type (BI_header_type), rval, extra), NULL_PTR); exp1 = build (MODIFY_EXPR, void_type_node, - build_component_ref (cookie, nc_nelts_field_id, NULL_TREE, 0), + build_component_ref (cookie, nc_nelts_field_id, + NULL_TREE, 0), nelts); TREE_SIDE_EFFECTS (exp1) = 1; rval = cp_convert (build_pointer_type (true_type), rval); - TREE_CALLS_NEW (rval) = 1; - TREE_SIDE_EFFECTS (rval) = 1; - rval = build_compound_expr (expr_tree_cons (NULL_TREE, exp1, - build_expr_list (NULL_TREE, rval))); + rval = build_compound_expr + (expr_tree_cons (NULL_TREE, exp1, + build_expr_list (NULL_TREE, rval))); } if (rval == error_mark_node) @@ -2596,7 +2638,6 @@ build_new (placement, decl, init, use_global_new) rval); TREE_NO_UNUSED_WARNING (rval) = 1; TREE_SIDE_EFFECTS (rval) = 1; - TREE_CALLS_NEW (rval) = 1; } else if (! has_array) { @@ -2631,88 +2672,6 @@ build_new (placement, decl, init, use_global_new) else rval = build (VEC_INIT_EXPR, TREE_TYPE (rval), save_expr (rval), init, nelts); -#if 0 - else if (current_function_decl == NULL_TREE) - { - extern tree static_aggregates; - - /* In case of static initialization, SAVE_EXPR is good enough. */ - rval = save_expr (rval); - rval = copy_to_permanent (rval); - init = copy_to_permanent (init); - init = expand_vec_init (decl, rval, - build_binary_op (MINUS_EXPR, nelts, - integer_one_node, 1), - init, 0); - init = copy_to_permanent (init); - static_aggregates = perm_tree_cons (init, rval, static_aggregates); - } - else - { - /* Have to wrap this in RTL_EXPR for two cases: - in base or member initialization and if we - are a branch of a ?: operator. Since we - can't easily know the latter, just do it always. */ - tree xval = make_node (RTL_EXPR); - - /* If we want to check the value of the allocation expression, - and the number of elements in the array is not a constant, we - *must* expand the SAVE_EXPR for nelts in alloc_expr before we - expand it in the actual initialization. So we need to build up - an RTL_EXPR for alloc_expr. Sigh. */ - if (alloc_expr && ! TREE_CONSTANT (nelts)) - { - tree xval = make_node (RTL_EXPR); - rtx rtxval; - TREE_TYPE (xval) = TREE_TYPE (alloc_expr); - do_pending_stack_adjust (); - start_sequence_for_rtl_expr (xval); - emit_note (0, -1); - rtxval = expand_expr (alloc_expr, NULL_RTX, VOIDmode, EXPAND_NORMAL); - do_pending_stack_adjust (); - TREE_SIDE_EFFECTS (xval) = 1; - RTL_EXPR_SEQUENCE (xval) = get_insns (); - end_sequence (); - RTL_EXPR_RTL (xval) = rtxval; - TREE_TYPE (xval) = TREE_TYPE (alloc_expr); - alloc_expr = xval; - } - - TREE_TYPE (xval) = TREE_TYPE (rval); - do_pending_stack_adjust (); - start_sequence_for_rtl_expr (xval); - - /* As a matter of principle, `start_sequence' should do this. */ - emit_note (0, -1); - - rval = save_expr (rval); - rval = expand_vec_init (decl, rval, - build_binary_op (MINUS_EXPR, nelts, - integer_one_node, 1), - init, 0); - - do_pending_stack_adjust (); - - TREE_SIDE_EFFECTS (xval) = 1; - TREE_CALLS_NEW (xval) = 1; - RTL_EXPR_SEQUENCE (xval) = get_insns (); - end_sequence (); - - if (TREE_CODE (rval) == SAVE_EXPR) - { - /* Errors may cause this to not get evaluated. */ - if (SAVE_EXPR_RTL (rval) == 0) - SAVE_EXPR_RTL (rval) = const0_rtx; - RTL_EXPR_RTL (xval) = SAVE_EXPR_RTL (rval); - } - else - { - my_friendly_assert (TREE_CODE (rval) == VAR_DECL, 217); - RTL_EXPR_RTL (xval) = DECL_RTL (rval); - } - rval = xval; - } -#endif /* If any part of the object initialization terminates by throwing an exception and the new-expression does not contain a @@ -2811,10 +2770,6 @@ build_new (placement, decl, init, use_global_new) rval = build_c_cast (build_pointer_type (type), rval); } - if (pending_sizes) - rval = build_compound_expr (chainon (pending_sizes, - build_expr_list (NULL_TREE, rval))); - return rval; } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 0ab0e236dd5..117fb029936 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1396,7 +1396,6 @@ build_opfncall (code, flags, xarg1, xarg2, arg3) return rval; TREE_TYPE (rval) = xarg1; - TREE_CALLS_NEW (rval) = 1; return rval; } break;