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
This commit is contained in:
parent
ef720b21fd
commit
a0d5fba7d2
|
@ -1,3 +1,16 @@
|
|||
Mon Jan 12 01:35:18 1998 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* 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 <jason@yorick.cygnus.com>
|
||||
|
||||
* exception.cc (__eh_alloc, __eh_free): New fns.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
169
gcc/cp/init.c
169
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue