--- gcc/cp/expr.c 2018/04/24 18:20:22 1.1.1.1 +++ gcc/cp/expr.c 2018/04/24 18:27:18 1.1.1.2 @@ -1,6 +1,6 @@ /* Convert language-specific tree expression to rtl instructions, for GNU compiler. - Copyright (C) 1988, 1992, 1993 Free Software Foundation, Inc. + Copyright (C) 1988, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. This file is part of GNU CC. @@ -16,7 +16,8 @@ GNU General Public License for more deta You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ #include "config.h" @@ -104,9 +105,10 @@ cplus_expand_expr (exp, target, tmode, m && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0))) { - type = TYPE_POINTER_TO (type); + type = build_pointer_type (type); /* Don't clobber a value that might be part of a default parameter value. */ + mark_addressable (slot); if (TREE_PERMANENT (args)) args = tree_cons (0, build1 (ADDR_EXPR, type, slot), TREE_CHAIN (args)); @@ -130,8 +132,6 @@ cplus_expand_expr (exp, target, tmode, m } if (call_target) { - preserve_temp_slots (call_target); - /* Make this a valid memory address now. The code below assumes that it can compare rtx and make assumptions based on the result. The assumptions are true only if the address was @@ -139,11 +139,9 @@ cplus_expand_expr (exp, target, tmode, m call_target = validize_mem (call_target); } - preserve_temp_slots (DECL_RTL (slot)); call_exp = build (CALL_EXPR, type, func, args, 0); TREE_SIDE_EFFECTS (call_exp) = 1; - return_target = expand_expr (call_exp, call_target, mode, 0); - free_temp_slots (); + return_target = expand_call (call_exp, call_target, ignore); if (call_target == 0) { if (pcc_struct_return) @@ -151,17 +149,20 @@ cplus_expand_expr (exp, target, tmode, m extern int flag_access_control; int old_ac = flag_access_control; - tree init = build (RTL_EXPR, type, 0, return_target); + tree init = build_decl (VAR_DECL, 0, type); TREE_ADDRESSABLE (init) = 1; + DECL_RTL (init) = return_target; flag_access_control = 0; - expand_aggr_init (slot, init, 0); + expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING); flag_access_control = old_ac; if (TYPE_NEEDS_DESTRUCTOR (type)) { - init = build (RTL_EXPR, build_reference_type (type), 0, - XEXP (return_target, 0)); + init = build_decl (VAR_DECL, 0, + build_reference_type (type)); + DECL_RTL (init) = XEXP (return_target, 0); + init = maybe_build_cleanup (convert_from_reference (init)); if (init != NULL_TREE) expand_expr (init, 0, 0, 0); @@ -174,7 +175,7 @@ cplus_expand_expr (exp, target, tmode, m if (call_target != return_target) { - my_friendly_assert (! TYPE_NEEDS_CONSTRUCTING (type), 317); + my_friendly_assert (TYPE_HAS_TRIVIAL_INIT_REF (type), 317); if (GET_MODE (return_target) == BLKmode) emit_block_move (call_target, return_target, expr_size (exp), TYPE_ALIGN (type) / BITS_PER_UNIT); @@ -195,7 +196,7 @@ cplus_expand_expr (exp, target, tmode, m init = build (RTL_EXPR, return_type, 0, call_target); /* We got back a reference to the type we want. Now initialize target with that. */ - expand_aggr_init (slot, init, 0); + expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING); } if (DECL_RTL (slot) != target) @@ -225,6 +226,14 @@ cplus_expand_expr (exp, target, tmode, m expand_throw (TREE_OPERAND (exp, 0)); return NULL; + case UNSAVE_EXPR: + { + rtx temp; + temp = expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier); + TREE_OPERAND (exp, 0) = unsave_expr_now (TREE_OPERAND (exp, 0)); + return temp; + } + default: break; } @@ -264,7 +273,7 @@ fixup_result_decl (decl, result) REG_FUNCTION_VALUE_P (real_decl_result) = 1; result = real_decl_result; } - emit_move_insn (result, DECL_RTL (decl)); + store_expr (decl, result, 0); emit_insn (gen_rtx (USE, VOIDmode, result)); } } @@ -274,9 +283,90 @@ fixup_result_decl (decl, result) in some cases. We cannot use `memory_operand' as a test here because on most RISC machines, a variable's address is not, by itself, a legitimate address. */ + int decl_in_memory_p (decl) tree decl; { return DECL_RTL (decl) != 0 && GET_CODE (DECL_RTL (decl)) == MEM; } + +/* Expand this initialization inline and see if it's simple enough that + it can be done at compile-time. */ + +static tree +extract_aggr_init (decl, init) + tree decl, init; +{ + return 0; +} + +static tree +extract_scalar_init (decl, init) + tree decl, init; +{ + rtx value, insns, insn; + extern struct obstack temporary_obstack; + tree t = NULL_TREE; + + push_obstacks (&temporary_obstack, &temporary_obstack); + start_sequence (); + value = expand_expr (init, NULL_RTX, VOIDmode, 0); + insns = get_insns (); + end_sequence (); + reg_scan (insns, max_reg_num (), 0); + jump_optimize (insns, 0, 0, 1); + pop_obstacks (); + + for (insn = insns; insn; insn = NEXT_INSN (insn)) + { + rtx r, to; + + if (GET_CODE (insn) == NOTE) + continue; + else if (GET_CODE (insn) != INSN) + return 0; + + r = PATTERN (insn); + if (GET_CODE (r) != SET) + return 0; + + to = XEXP (r, 0); + + if (! (to == value || + (GET_CODE (to) == SUBREG && XEXP (to, 0) == value))) + return 0; + + r = XEXP (r, 1); + + switch (GET_CODE (r)) + { + case CONST_INT: + t = build_int_2 (XEXP (r, 0), 0); + break; + default: + return 0; + } + } + + return t; +} + +int +extract_init (decl, init) + tree decl, init; +{ + return 0; + + if (IS_AGGR_TYPE (TREE_TYPE (decl)) + || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) + init = extract_aggr_init (decl, init); + else + init = extract_scalar_init (decl, init); + + if (init == NULL_TREE) + return 0; + + DECL_INITIAL (decl) = init; + return 1; +}