OSDN Git Service

* gcc-interface/trans.c (call_to_gnu): In the return-by-target-ptr case
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Apr 2010 10:49:53 +0000 (10:49 +0000)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 05:17:20 +0000 (14:17 +0900)
do not set the result type if there is a specified target and do not
convert the result in any cases.
(protect_multiple_eval): Make direct SAVE_EXPR for CALL_EXPR.
(maybe_stabilize_reference) <COMPOUND_EXPR>: Merge with CALL_EXPR.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158053 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ada/ChangeLog
gcc/ada/gcc-interface/trans.c

index 822790b..89f5cad 100644 (file)
@@ -1,665 +1,3 @@
-2010-05-18  Nathan Froyd  <froydnj@codesourcery.com>
-
-       * gcc-interface/trans.c (call_to_gnu): Use build_call_vec instead of
-       build_call_list.
-       * gcc-interface/utils.c (build_function_stub): Likewise.
-
-2010-05-16  Manuel López-Ibáñez  <manu@gcc.gnu.org>
-
-       * gcc-interface/misc.c (gnat_handle_option): Remove special logic
-       for Wuninitialized without -O.
-       
-2010-05-16  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/gigi.h (enum standard_datatypes): Add new value
-       ADT_exception_data_name_id.
-       (exception_data_name_id): New define.
-       * gcc-interface/trans.c (gigi): Initialize it.
-       * gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Use the standard
-       exception type for standard exception definitions.  Do not make them
-       volatile.
-       <E_Record_Type>: Equate fields of types associated with an exception
-       definition to those of the standard exception type.
-
-2010-05-13  Andreas Schwab  <schwab@linux-m68k.org>
-
-       * tracebak.c (__gnat_backtrace): Mark top_stack with ATTRIBUTE_UNUSED.
-
-2010-05-12  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Access_Type>: Tidy up
-       code, improve comments and fix formatting nits.
-
-2010-05-12  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/utils.c (update_pointer_to): Return early if the old
-       pointer already points to the new type.  Chain the old pointer and its
-       variants at the end of new pointer's chain after updating them.
-
-2010-05-10  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * exp_disp.adb (Make_Tags): Mark the imported view of dispatch tables
-       built for interfaces.
-       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Use
-       imported_p instead of Is_Imported when considering constants.
-       Do not promote alignment of exported objects.
-       <E_Record_Subtype>: Strip all suffixes for dispatch table entities.
-
-2010-05-08  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * exp_disp.adb (Make_Tags): Mark the imported view of dispatch tables.
-       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Make imported
-       constants really constant.
-       <E_Record_Subtype>: Strip the suffix for dispatch table entities.
-
-2010-05-08  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/decl.c (make_aligning_type): Declare the type.
-
-2010-05-08  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/decl.c (gnat_to_gnu_entity): Create variables for size
-       expressions of variant part of record types declared at library level.
-
-2010-05-08  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/gigi.h (create_field_decl): Move PACKED parameter.
-       * gcc-interface/utils.c (create_field_decl): Move PACKED parameter.
-       (rest_of_record_type_compilation): Adjust call to create_field_decl.
-       (make_descriptor_field): Likewise and pass correctly typed constants.
-       (build_unc_object_type): Likewise.
-       (unchecked_convert): Likewise.
-       * gcc-interface/decl.c (elaborate_expression_2): New static function.
-       (gnat_to_gnu_entity): Use it to make alignment factors explicit.
-       Adjust call to create_field_decl.
-       (make_aligning_type): Likewise.
-       (make_packable_type): Likewise.
-       (maybe_pad_type): Likewise.
-       (gnat_to_gnu_field): Likewise.
-       (components_to_record): Likewise.
-       (create_field_decl_from): Likewise.
-       (create_variant_part_from): Remove superfluous test.
-       * gcc-interface/trans.c (gigi): Adjust call to create_field_decl.
-
-2010-05-08  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/gigi.h (build_unc_object_type): Add DEBUG_INFO_P param.
-       (build_unc_object_type_from_ptr): Likewise.
-       * gcc-interface/utils.c (build_unc_object_type): Add DEBUG_INFO_P param
-       and pass it to create_type_decl.  Declare the type.  Simplify.
-       (build_unc_object_type_from_ptr): Add DEBUG_INFO_P parameter and pass
-       it to build_unc_object_type.
-       * gcc-interface/decl.c (gnat_to_gnu_entity): Adjust to above change.
-       * gcc-interface/trans.c (Attribute_to_gnu): Likewise.
-       (gnat_to_gnu): Likewise.
-       * gcc-interface/utils2.c (build_allocator): Likewise.
-
-2010-05-07 Eric Botcazou  <ebotcazou@adacore.com>
-
-       PR 40989
-       * gcc-interface/misc.c (gnat_handle_option): Fix long line.
-
-2010-05-06  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
-
-       * gcc-interface/Makefile.in: Removed mips-sgi-irix5* support.
-
-2010-05-06  Manuel López-Ibáñez  <manu@gcc.gnu.org>
-
-       PR 40989
-       * gcc-interface/misc.c (gnat_handle_option): Add argument kind.
-
-2010-05-02  Giuseppe Scrivano  <gscrivano@gnu.org>
-
-       * gnathtml.pl: Use 755 as mask for new directories.
-
-2010-04-28  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/trans.c (gnat_gimplify_expr) <ADDR_EXPR>: Uniquize
-       constant constructors before taking their address.
-
-2010-04-25  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * exp_dbug.ads: Fix outdated description.  Mention link between XVS
-       and XVZ objects.
-       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Subtype>: Set
-       XVZ variable as unit size of XVS type.
-       (maybe_pad_type): Likewise.
-
-2010-04-25  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/trans.c (gnat_to_gnu) <N_Assignment_Statement>: Do not
-       use memmove if the array type is bit-packed.
-
-2010-04-18  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/misc.c (gnat_init): Remove second argument in call to
-       build_common_tree_nodes.
-
-2010-04-18  Ozkan Sezer  <sezeroz@gmail.com>
-
-       * gsocket.h: Make sure that winsock2.h is included before windows.h.
-
-2010-04-17  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/utils2.c (build_unary_op) <ATTR_ADDR_EXPR>: Do not
-       issue warning.
-
-2010-04-17  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * uintp.h (UI_Lt): Declare.
-       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Type>: Do the size
-       computation in sizetype.
-       <E_Array_Subtype>: Use unified handling for all index types.  Do not
-       generate MAX_EXPR-based expressions, only COND_EXPR-based ones.  Add
-       bypass for PATs.
-       (annotate_value): Change test for negative values.
-       (validate_size): Apply test for negative values on GNAT nodes.
-       (set_rm_size): Likewise.
-       * gcc-interface/misc.c (gnat_init): Set unsigned types for sizetypes.
-       * gcc-interface/utils.c (rest_of_record_type_compilation): Change test
-       for negative values.
-       (max_size) <MINUS_EXPR>: Do not reassociate a COND_EXPR on the LHS.
-       (builtin_type_for_size): Adjust definition of signed_size_type_node.
-       * gcc-interface/utils2.c (compare_arrays): Optimize comparison of
-       lengths against zero.
-
-2010-04-17  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * back-end.adb (Call_Back_End): Pass Standard_Character to gigi.
-       * gcc-interface/gigi.h (gigi): Add standard_character parameter.
-       (CHAR_TYPE_SIZE, SHORT_TYPE_SIZE, INT_TYPE_SIZE, LONG_TYPE_SIZE, 
-       LONG_LONG_TYPE_SIZE, FLOAT_TYPE_SIZE, DOUBLE_TYPE_SIZE,
-       LONG_DOUBLE_TYPE_SIZE, SIZE_TYPE): Delete.
-       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Subtype>: Call
-       rm_size.
-       * gcc-interface/misc.c (gnat_init): Set signedness of char as per
-       flag_signed_char.  Tag sizetype with "size_type" moniker.
-       * gcc-interface/trans.c (gigi): Add standard_character parameter.
-       Remove useless built-in types.  Equate unsigned_char_type_node to
-       Standard.Character.  Use it instead of char_type_node throughout.
-       (Attribute_to_gnu): Likewise.
-       (gnat_to_gnu): Likewise.
-       * gcc-interface/utils2.c (build_call_raise): Likewise.
-
-2010-04-17  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/gigi.h (enum standard_datatypes): Add new values
-       ADT_sbitsize_one_node and ADT_sbitsize_unit_node.
-       (sbitsize_one_node): New macro.
-       (sbitsize_unit_node): Likewise.
-       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Subtype>: Fix
-       latent bug in the computation of subrange_p.  Fold wider_p predicate.
-       (cannot_be_superflat_p): Use an explicitly signed 64-bit type to do
-       the final comparison.
-       (make_aligning_type): Build real negation and use sizetype throughout
-       the offset computation.
-       (maybe_pad_type): Do not issue the warning when the new size expression
-       is too complex.
-       (annotate_value) <INTEGER_CST>: Simplify code handling negative values.
-       * gcc-interface/misc.c (gnat_init): Initialize sbitsize_one_node and
-       sbitsize_unit_node.
-       * gcc-interface/trans.c (Attribute_to_gnu) <Attr_Pool_Address>: Fold
-       double negation.
-       (gnat_to_gnu) <N_Free_Statement>: Likewise.
-       * gcc-interface/utils.c (convert): Use sbitsize_unit_node.
-       * gcc-interface/utils2.c (compare_arrays): Compute real lengths and use
-       constants in sizetype.  Remove dead code and tweak comments.  Generate
-       equality instead of inequality comparisons for zero length tests.
-
-2010-04-16  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/gigi.h (gnat_init_decl_processing): Delete.
-       * gcc-interface/decl.c (gnat_to_gnu_entity): Constify a few variables.
-       <object>: Do not create the fake PARM_DECL if no debug info is needed.
-       Do not create the corresponding VAR_DECL of a CONST_DECL for debugging
-       purposes if no debug info is needed.
-       Fix formatting.  Reorder and add comments.
-       * gcc-interface/trans.c (gnat_to_gnu) <N_Attribute_Reference>: Constify
-       variable and remove obsolete comment.
-       * gcc-interface/utils.c (convert_vms_descriptor64): Tweak comment.
-       (convert_vms_descriptor32): Likewise.
-       (convert): Remove dead code.
-       <UNCONSTRAINED_ARRAY_REF>: Pass the field instead of its name to build
-       the reference to the P_ARRAY pointer.
-       <POINTER_TYPE>: Likewise.
-       (maybe_unconstrained_array) <UNCONSTRAINED_ARRAY_TYPE>: Likewise.
-       (gnat_init_decl_processing): Delete, move contents to...
-       * gcc-interface/misc.c (gnat_init): ...here.
-
-2010-04-16  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/trans.c (unchecked_conversion_nop): Handle function
-       calls.  Return true for conversion from a record subtype to its type.
-
-2010-04-16  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/decl.c (gnat_to_gnu_entity): Use boolean_type_node in
-       lieu of integer_type_node for boolean operations.
-       (choices_to_gnu): Likewise.
-       * gcc-interface/trans.c (Attribute_to_gnu): Likewise.
-       (Loop_Statement_to_gnu): Likewise.
-       (establish_gnat_vms_condition_handler): Likewise.
-       (Exception_Handler_to_gnu_sjlj): Likewise.
-       (gnat_to_gnu): Likewise.
-       (build_unary_op_trapv): Likewise.
-       (build_binary_op_trapv): Likewise.
-       (emit_range_check): Likewise.
-       (emit_index_check): Likewise.
-       (convert_with_check): Likewise.
-       * gcc-interface/utils.c (convert_vms_descriptor64): Likewise.
-       (convert_vms_descriptor32): Likewise.
-       (convert_vms_descriptor): Likewise.
-       * gcc-interface/utils2.c (nonbinary_modular_operation): Likewise.
-       (compare_arrays): Use boolean instead of integer constants.
-       (build_binary_op) <TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR, TRUTH_AND_EXPR,
-       TRUTH_OR_EXPR, TRUTH_XOR_EXPR>: New case.  Check that the result type
-       is a boolean type.
-       <GE_EXPR, LE_EXPR, GT_EXPR, LT_EXPR>: Remove obsolete assertion.
-       <EQ_EXPR, NE_EXPR>: Check that the result type is a boolean type.
-       <PREINC/PREDECREMENT_EXPR, POSTINC/POSTDECREMENT_EXPR>: Delete.
-       <TRUTH_NOT_EXPR>: Check that the result type is a boolean type.
-       (build_unary_op): Use boolean_type_node in lieu of integer_type_node
-       for boolean operations.
-       (fill_vms_descriptor): Likewise.  Fix formatting nits.
-
-2010-04-16  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/ada-tree.def (LOOP_STMT): Change to 4-operand nodes.
-       * gcc-interface/ada-tree.h (LOOP_STMT_TOP_COND, LOOP_STMT_BOT_COND):
-       Merge into...
-       (LOOP_STMT_COND): ...this.
-       (LOOP_STMT_BOTTOM_COND_P): New flag.
-       (LOOP_STMT_TOP_UPDATE_P): Likewise.
-       * gcc-interface/trans.c (can_equal_min_or_max_val_p): New function.
-       (can_equal_min_val_p): New static inline function.
-       (can_equal_max_val_p): Likewise.
-       (Loop_Statement_to_gnu): Use build4 in lieu of build5 and adjust to
-       new LOOP_STMT semantics.  Use two different strategies depending on
-       whether optimization is enabled to translate the loop.
-       (gnat_gimplify_stmt) <LOOP_STMT>: Adjust to new LOOP_STMT semantics.
-
-2010-04-16  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * uintp.adb (UI_From_Dint): Remove useless code.
-       (UI_From_Int): Likewise.
-       * uintp.h: Reorder declarations.
-       (UI_From_gnu): Declare.
-       (UI_Base): Likewise.
-       (Vector_Template): Likewise.
-       (Vector_To_Uint): Likewise.
-       (Uint_0): Remove.
-       (Uint_1): Likewise.
-       * gcc-interface/gigi.h: Tweak comments.
-       * gcc-interface/cuintp.c (UI_From_gnu): New global function.
-       * gcc-interface/decl.c (maybe_pad_type): Do not warn if either size
-       overflows.
-       (annotate_value) <INTEGER_CST>: Call UI_From_gnu.
-       * gcc-interface/trans.c (post_error_ne_num): Call post_error_ne.
-       (post_error_ne_tree): Call UI_From_gnu and post_error_ne.
-       * gcc-interface/utils.c (max_size) <tcc_binary>: Do not special-case
-       TYPE_MAX_VALUE.
-
-2010-04-16  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/decl.c (make_type_from_size) <INTEGER_TYPE>: Just copy
-       TYPE_NAME.
-       * gcc-interface/trans.c (smaller_packable_type_p): Rename into...
-       (smaller_form_type_p): ...this.  Change parameter and variable names.
-       (call_to_gnu): Use the nominal type of the parameter to create the
-       temporary if it's a smaller form of the actual type.
-       (addressable_p): Return false if the actual type is integral and its
-       size is greater than that of the expected type.
-
-2010-04-15  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/cuintp.c (UI_To_gnu): Fix long line.
-       * gcc-interface/gigi.h (MARK_VISITED): Skip objects of constant class.
-       (process_attributes): Delete.
-       (post_error_ne_num): Change parameter name.
-       * gcc-interface/decl.c (gnat_to_gnu_entity): Do not force debug info
-       with -g3.  Remove a couple of obsolete lines.  Minor tweaks.
-       If type annotating mode, operate on trees to compute the adjustment to
-       the sizes of tagged types.  Fix long line.
-       (cannot_be_superflat_p): Tweak head comment.
-       (annotate_value): Fold local constant.
-       (set_rm_size): Fix long line.
-       * gcc-interface/trans.c (Identifier_to_gnu): Rework comments.
-       (Attribute_to_gnu): Fix long line.
-       <Attr_Size>: Remove useless assertion.
-       Reorder statements.  Use size_binop routine.
-       (Loop_Statement_to_gnu): Use build5 in lieu of build_nt.
-       Create local variables for the label and the test.  Tweak comments.
-       (Subprogram_Body_to_gnu): Reset cfun to NULL.
-       (Compilation_Unit_to_gnu): Use the Sloc of the Unit node.
-       (process_inlined_subprograms): Integrate into...
-       (Compilation_Unit_to_gnu): ...this.
-       (gnat_to_gnu): Fix long line.
-       (post_error_ne_num): Change parameter name.
-       * gcc-interface/utils.c (process_attributes): Static-ify.
-       <ATTR_MACHINE_ATTRIBUTE>: Set input_location before proceeding.
-       (create_type_decl): Add comment.
-       (create_var_decl_1): Process the attributes after adding the VAR_DECL
-       to the current binding level.
-       (create_subprog_decl): Likewise for the FUNCTION_DECL.
-       (end_subprog_body): Do not reset cfun to NULL.
-       (build_vms_descriptor32): Fix long line.
-       (build_vms_descriptor): Likewise.
-       (handle_nonnull_attribute): Likewise.
-       (convert_vms_descriptor64): Likewise.
-       * gcc-interface/utils2.c (fill_vms_descriptor): Fix long line.
-       (gnat_protect_expr): Fix thinko.
-
-2010-04-15  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/trans.c (gigi): Set DECL_IGNORED_P on EH functions.
-       (gnat_to_gnu) <N_Op_Eq>: Restore the value of input_location
-       before translating the top-level node.
-       (lvalue_required_p) <N_Function_Call>: Return 1 if !constant.
-       <N_Object_Declaration>: Likewise.
-       <N_Assignment_Statement>: Likewise.
-       <N_Unchecked_Type_Conversion>: Likewise.
-       (call_to_gnu): Remove kludge.
-       (gnat_to_gnu) <N_Return_Statement>: When not optimizing, force labels
-       associated with user returns to be preserved.
-       (gnat_to_gnu): Add special code to deal with boolean rvalues.
-       * gcc-interface/utils2.c (compare_arrays): Set input_location on all
-       comparisons.
-       (build_unary_op) <ADDR_EXPR>: Call build_fold_addr_expr.
-       <INDIRECT_REF>: Call build_fold_indirect_ref.
-
-2010-04-15  Joel Sherrill  <joel.sherrill@oarcorp.com>
-
-       * g-socket.adb: A target can have multiple missing errno's.  This
-       will result in multiple errno's being defined as -1.  Because of this
-       we can not use a case but must use a series of if's to avoid 
-       a duplicate case error in GNAT.Sockets.Resolve_Error.
-
-2010-04-15  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/trans.c (call_to_gnu): Open a nesting level if this is
-       a statement.  Otherwise, if at top-level, push the processing of the
-       elaboration routine.  In the misaligned case, issue the error messages
-       again on entry and create the temporary explicitly.  Do not issue them
-       for CONSTRUCTORs.
-       For a function call, emit the range check if necessary.
-       In the copy-in copy-out case, create the temporary for the return
-       value explicitly.
-       Do not unnecessarily convert by-ref parameters to the formal's type.
-       Remove obsolete guards in conditions.
-       (gnat_to_gnu) <N_Assignment_Statement>: For a function call, pass the
-       target to call_to_gnu in all cases.
-       (gnat_gimplify_expr) <ADDR_EXPR>: Remove handling of SAVE_EXPR.
-       (addressable_p) <CONSTRUCTOR>: Return false if not static.
-       <COMPOUND_EXPR>: New case.
-       * gcc-interface/utils2.c (build_unary_op) <ADDR_EXPR>: Fold a compound
-       expression if it has unconstrained array type.
-       (gnat_mark_addressable) <COMPOUND_EXPR>: New case.
-       (gnat_stabilize_reference) <COMPOUND_EXPR>: Stabilize operands on an
-       individual basis.
-
-2010-04-15  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/trans.c (gigi): Do not start statement group.
-       (Compilation_Unit_to_gnu): Set current_function_decl to NULL.
-       Start statement group and push binding level here...
-       (gnat_to_gnu) <N_Compilation_Unit>: ...and not here.
-       Do not push fake contexts at top level.  Remove redundant code.
-       (call_to_gnu): Rename a local variable and constify another.
-       * gcc-interface/utils.c (gnat_pushlevel): Fix formatting nits.
-       (set_current_block_context): Set it as the group's block.
-       (gnat_init_decl_processing): Delete unrelated init code.
-       (end_subprog_body): Use NULL_TREE.
-
-2010-04-15  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/trans.c (call_to_gnu): Do not unnecessarily force
-       side-effects of actual parameters before the call.
-
-2010-04-15  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/decl.c (validate_size): Reorder, remove obsolete test
-       and warning.
-       (set_rm_size): Reorder and remove obsolete test.
-
-2010-04-14  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/gigi.h: Reorder declarations and tweak comments.
-       (gigi): Adjust ATTRIBUTE_UNUSED markers.
-       * gcc-interface/gadaint.h: New file.
-       * gcc-interface/trans.c: Include it in lieu of adaint.h.  Reorder.
-       (__gnat_to_canonical_file_spec): Remove declaration.
-       (number_names): Delete.
-       (number_files): Likewise.
-       (gigi): Adjust.
-       * gcc-interface/Make-lang.in (ada/trans.o): Adjust dependencies to
-       above change.
-
-2010-04-14  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Class_Wide_Type>: Fix
-       comment.
-       * gcc-interface/trans.c (process_freeze_entity): Use local copy of
-       Ekind.  Return early for class-wide types.  Do not compute initializer
-       unless necessary.  Reuse the tree for an associated class-wide type
-       only if processing its root type.
-
-2010-04-13  Joel Sherrill  <joel.sherrill@oarcorp.com>
-
-       * gsocket.h: Run-time can no longer be built without network
-       OS headers available.  Changing RTEMS GNAT build procedure to
-       reflect this and letting run-time build use network .h files.
-
-2010-04-13  Duncan Sands  <baldrick@free.fr>
-
-       * gcc-interface/misc.c (gnat_eh_type_covers): Remove.
-       * gcc-interface/trans.c (Exception_Handler_to_gnu_zcx): Update comment.
-
-2010-04-13  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/gigi.h (standard_datatypes): Add ADT_parent_name_id.
-       (parent_name_id): New macro.
-       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Type>: Use it.
-       * gcc-interface/trans.c (gigi): Initialize it.
-       (lvalue_required_p) <N_Type_Conversion>: New case.
-       <N_Qualified_Expression>: Likewise.
-       <N_Allocator>: Likewise.
-       * gcc-interface/utils.c (convert): Try to properly upcast tagged types.
-
-2010-04-13  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/ada-tree.h (TYPE_BY_REFERENCE_P): Delete.
-       (DECL_CONST_ADDRESS_P): New macro.
-       (SET_DECL_ORIGINAL_FIELD_TO_FIELD): Likewise.
-       (SAME_FIELD_P): Likewise.
-       * gcc-interface/decl.c (constructor_address_p): New static function.
-       (gnat_to_gnu_entity) <object>: Set DECL_CONST_ADDRESS_P according to
-       the return value of above function.
-       (gnat_to_gnu_entity) <E_Record_Type>: Force BLKmode for all types
-       passed by reference.
-       <E_Record_Subtype>: Likewise.
-       Set TREE_ADDRESSABLE on the type if it passed by reference.
-       (make_packable_type): Use SET_DECL_ORIGINAL_FIELD_TO_FIELD.
-       (create_field_decl_from): Likewise.
-       (substitute_in_type): Likewise.
-       (purpose_member_field): Use SAME_FIELD_P.
-       * gcc-interface/misc.c (must_pass_by_ref): Test TREE_ADDRESSABLE.
-       * gcc-interface/trans.c (lvalue_required_p): Add ADDRESS_OF_CONSTANT
-       parameter and adjust recursive calls.
-       <N_Explicit_Dereference>: New case.
-       <N_Object_Declaration>: Return 1 if the object is of a class-wide type.
-       Adjust calls to lvalue_required_p.  Do not return the initializer of a
-       DECL_CONST_ADDRESS_P constant if an lvalue is required for it.
-       (call_to_gnu): Delay issuing error message for a misaligned actual and
-       avoid the associated back-end assertion.  Test TREE_ADDRESSABLE.
-       (gnat_gimplify_expr) <ADDR_EXPR>: Handle non-static constructors.
-       * gcc-interface/utils.c (make_dummy_type): Set TREE_ADDRESSABLE if the
-       type is passed by reference.
-       (convert) <CONSTRUCTOR>: Convert in-place in more cases.
-       * gcc-interface/utils2.c (build_cond_expr): Drop TYPE_BY_REFERENCE_P.
-       (build_simple_component_ref): Use SAME_FIELD_P.
-
-2010-04-12  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/trans.c (Identifier_to_gnu): Use boolean variable.
-       (call_to_gnu): Test gigi's flag TYPE_BY_REFERENCE_P instead of calling
-       front-end's predicate Is_By_Reference_Type.  Use consistent order and
-       remove ??? comment.  Use original conversion in all cases, if any.
-       * gcc-interface/utils.c (make_dummy_type): Minor tweak.
-       (convert): Use local copy in more cases.
-       <INDIRECT_REF>: Remove deactivated code.
-       (unchecked_convert): Use a couple of local copies.
-
-2010-04-11  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/trans.c (lvalue_required_for_attribute_p): New static
-       function.
-       (lvalue_required_p) <N_Attribute_Reference>: Call it.
-       (gnat_to_gnu) <N_Selected_Component>: Prevent build_component_ref from
-       folding the result only if lvalue_required_for_attribute_p is true.
-       * gcc-interface/utils.c (maybe_unconstrained_array): Pass correctly
-       typed constant to build_component_ref.
-       (unchecked_convert): Likewise.
-       * gcc-interface/utils2.c (maybe_wrap_malloc): Likewise.
-       (build_allocator): Likewise.
-
-2010-04-11  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/utils2.c (build_cond_expr): Take the address and
-       dereference if the result type is passed by reference.
-
-2010-04-11  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/trans.c (Case_Statement_to_gnu): Bool-ify variable.
-       (gnat_to_gnu) <N_Null_Statement>: When not optimizing, generate a
-       goto to the next statement.
-
-2010-04-09  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/gigi.h (maybe_variable): Delete.
-       (protect_multiple_eval): Likewise.
-       (maybe_stabilize_reference): Likewise.
-       (gnat_save_expr): Declare.
-       (gnat_protect_expr): Likewise.
-       (gnat_stabilize_reference): Likewise.
-       * gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Use
-       gnat_stabilize_reference.
-       (maybe_variable): Delete.
-       (elaborate_expression_1): Use gnat_save_expr.
-       * gcc-interface/trans.c (Attribute_to_gnu): Use gnat_protect_expr.
-       (call_to_gnu): Pass NULL to gnat_stabilize_reference.
-       (gnat_to_gnu) <N_Object_Declaration>: Use gnat_save_expr.
-       <N_Slice>: Use gnat_protect_exp.
-       <N_Selected_Component>: Pass NULL to gnat_stabilize_reference.
-       <N_In>: Use gnat_protect_expr.
-       Pass NULL to gnat_stabilize_reference.
-       (build_unary_op_trapv): Use gnat_protect_expr.
-       (build_binary_op_trapv): Likewise.
-       (emit_range_check): Likewise.
-       (emit_index_check): Likewise.
-       (convert_with_check): Likewise.
-       (protect_multiple_eval): Move to utils2.c file.
-       (maybe_stabilize_reference): Merge into...
-       (gnat_stabilize_reference): ...this.  Move to utils2.c file.
-       (gnat_stabilize_reference_1): Likewise.
-       * gcc-interface/utils.c (convert_to_fat_pointer): Use gnat_protect_expr
-       instead of protect_multiple_eval.
-       * gcc-interface/utils2.c (compare_arrays): Likewise.
-       (nonbinary_modular_operation): Likewise.
-       (maybe_wrap_malloc): Likewise.
-       (build_allocator): Likewise.
-       (gnat_save_expr): New function.
-       (gnat_protect_expr): Rename from protect_multiple_eval.  Early return
-       in common cases.  Propagate TREE_READONLY onto dereferences.
-       (gnat_stabilize_reference_1): Move from trans.c file.
-       (gnat_stabilize_reference): Likewise.
-
-2010-04-09  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/gigi.h (gnat_mark_addressable): Rename parameter.
-       * gcc-interface/decl.c (maybe_variable): Do not set TREE_STATIC on _REF
-       node.  Use the type of the operand to set TREE_READONLY.
-       * gcc-interface/trans.c (Identifier_to_gnu): Do not set TREE_STATIC on
-       _REF node.  Do not overwrite TREE_READONLY.
-       (call_to_gnu): Rename local variable and fix various nits.  In the
-       copy-in/copy-out case, build the SAVE_EXPR manually.
-       (convert_with_check): Call protect_multiple_eval in lieu of save_expr
-       and fold the computations.
-       (protect_multiple_eval): Always save entire fat pointers.
-       (maybe_stabilize_reference): Minor tweaks.
-       (gnat_stabilize_reference_1): Likewise.  Do not deal with tcc_constant,
-       tcc_type and tcc_statement.
-       * gcc-interface/utils.c (convert_to_fat_pointer): Call
-       protect_multiple_eval in lieu of save_expr.
-       (convert): Minor tweaks.
-       (maybe_unconstrained_array): Do not set TREE_STATIC on _REF node.
-       (builtin_type_for_size): Call gnat_type_for_size directly.
-       * gcc-interface/utils2.c (contains_save_expr_p): Delete.
-       (contains_null_expr): Likewise
-       (gnat_build_constructor): Do not call it.
-       (compare_arrays): Deal with all side-effects, use protect_multiple_eval
-       instead of gnat_stabilize_reference to protect the operands.
-       (nonbinary_modular_operation): Call protect_multiple_eval in lieu of
-       save_expr.
-       (maybe_wrap_malloc): Likewise.
-       (build_allocator): Likewise.
-       (build_unary_op) <INDIRECT_REF>: Do not set TREE_STATIC on _REF node.
-       (gnat_mark_addressable): Rename parameter.
-
-2010-04-08  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/ada-tree.h (TYPE_RETURNS_UNCONSTRAINED_P): Rename into.
-       (TYPE_RETURN_UNCONSTRAINED_P): ...this.
-       (TYPE_RETURNS_BY_REF_P): Rename into.
-       (TYPE_RETURN_BY_DIRECT_REF_P): ...this.
-       (TYPE_RETURNS_BY_TARGET_PTR_P): Delete.
-       * gcc-interface/gigi.h (create_subprog_type): Adjust parameter names.
-       (build_return_expr): Likewise.
-       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Subprogram_Type>:
-       Rename local variables.  If the return Mechanism is By_Reference, pass
-       return_by_invisible_ref_p to create_subprog_type instead of toggling
-       TREE_ADDRESSABLE.  Test return_by_invisible_ref_p in order to annotate
-       the mechanism.  Use regular return for contrained types with non-static
-       size and return by invisible reference for unconstrained return types
-       with default discriminants.  Update comment.
-       * gcc-interface/trans.c (Subprogram_Body_to_gnu): If the function
-       returns by invisible reference, turn the RESULT_DECL into a pointer.
-       Do not handle DECL_BY_REF_P in the CICO case here.
-       (call_to_gnu): Remove code handling return by target pointer.  For a
-       function call, if the return type has non-constant size, generate the
-       assignment with an INIT_EXPR.
-       (gnat_to_gnu) <N_Return_Statement>: Remove dead code in the CICO case.
-       If the function returns by invisible reference, build the copy return
-       operation manually.
-       (add_decl_expr): Initialize the variable with an INIT_EXPR.
-       * gcc-interface/utils.c (create_subprog_type): Adjust parameter names.
-       Adjust for renaming of macros.  Copy the node only when necessary.
-       (create_subprog_decl): Do not toggle TREE_ADDRESSABLE on the return
-       type, only change DECL_BY_REFERENCE on the RETURN_DECL.
-       (convert_from_reference): Delete.
-       (is_byref_result): Likewise.
-       (gnat_genericize_r): Likewise.
-       (gnat_genericize): Likewise.
-       (end_subprog_body): Do not call gnat_genericize.
-       * gcc-interface/utils2.c (build_binary_op) <INIT_EXPR>: New case.
-       (build_return_expr): Adjust parameter names, logic and comment.
-
-2010-04-07  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * exp_pakd.adb (Create_Packed_Array_Type): Always use a modular type
-       if the size is small enough.  Propagate the alignment if there is an
-       alignment clause on the original array type.
-       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Modular_Integer_Subtype>
-       Deal with under-aligned packed array types.  Copy the size onto the
-       justified modular type and don't lay it out again.  Likewise for the
-       padding type built for other under-aligned subtypes.
-       * gcc-interface/utils.c (finish_record_type): Do not set a default mode
-       on the type.
-
-2010-04-07  Eric Botcazou  <ebotcazou@adacore.com>
-
-       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Procedure>: Set default
-       alignment on the RETURN type built for the Copy-In Copy-Out mechanism.
-
 2010-04-07  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/trans.c (call_to_gnu): In the return-by-target-ptr case
index 13e9d1a..0f4cef0 100644 (file)
@@ -2646,8 +2646,28 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
 
       if (Nkind (gnat_node) == N_Function_Call && !gnu_target)
        {
-         *gnu_result_type_p = TREE_TYPE (gnu_subprog_type);
-         return build1 (NULL_EXPR, TREE_TYPE (gnu_subprog_type), call_expr);
+         tree gnu_obj_type;
+
+         if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_ret_type)))
+           gnu_obj_type
+             = maybe_pad_type (gnu_ret_type,
+                               max_size (TYPE_SIZE (gnu_ret_type), true),
+                               0, Etype (Name (gnat_node)), false, false,
+                               false, true);
+         else
+           gnu_obj_type = gnu_ret_type;
+
+         /* ??? We may be about to create a static temporary if we happen to
+            be at the global binding level.  That's a regression from what
+            the 3.x back-end would generate in the same situation, but we
+            don't have a mechanism in Gigi for creating automatic variables
+            in the elaboration routines.  */
+         gnu_target
+           = create_var_decl (create_tmp_var_name ("LR"), NULL, gnu_obj_type,
+                              NULL, false, false, false, false, NULL,
+                              gnat_node);
+
+         *gnu_result_type_p = gnu_ret_type;
        }
 
       return call_expr;
@@ -2976,14 +2996,36 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
       VEC_safe_push (tree, gc, gnu_actual_vec, gnu_actual);
     }
 
-  gnu_call = build_call_vec (TREE_TYPE (gnu_subprog_type), gnu_subprog_addr,
-                             gnu_actual_vec);
-  set_expr_location_from_node (gnu_call, gnat_node);
+  gnu_subprog_call = build_call_list (TREE_TYPE (gnu_subprog_type),
+                                     gnu_subprog_addr,
+                                     nreverse (gnu_actual_list));
+  set_expr_location_from_node (gnu_subprog_call, gnat_node);
+
+  /* If we return by passing a target, the result is the target after the
+     call.  We must not emit the call directly here because this might be
+     evaluated as part of an expression with conditions to control whether
+     the call should be emitted or not.  */
+  if (TYPE_RETURNS_BY_TARGET_PTR_P (gnu_subprog_type))
+    {
+      /* Conceptually, what we need is a COMPOUND_EXPR of the call followed by
+        the target object.  Doing so would potentially be inefficient though,
+        as this expression might be wrapped up into a SAVE_EXPR later, which
+        would incur a pointless temporary copy of the whole object.
+
+        What we do instead is build a COMPOUND_EXPR returning the address of
+        the target, and then dereference.  Wrapping up the COMPOUND_EXPR into
+        a SAVE_EXPR then only incurs a mere pointer copy.  */
+      tree gnu_target_addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_target);
+      set_expr_location_from_node (gnu_target_addr, gnat_node);
+      gnu_result = build2 (COMPOUND_EXPR, TREE_TYPE (gnu_target_addr),
+                          gnu_subprog_call, gnu_target_addr);
+      return build_unary_op (INDIRECT_REF, NULL_TREE, gnu_result);
+    }
 
-  /* If it's a function call, the result is the call expression unless a target
-     is specified, in which case we copy the result into the target and return
-     the assignment statement.  */
-  if (Nkind (gnat_node) == N_Function_Call)
+  /* If it is a function call, the result is the call expression unless
+     a target is specified, in which case we copy the result into the target
+     and return the assignment statement.  */
+  else if (Nkind (gnat_node) == N_Function_Call)
     {
       tree gnu_result = gnu_call;
 
@@ -7467,6 +7509,263 @@ maybe_implicit_deref (tree exp)
   return exp;
 }
 \f
+/* Protect EXP from multiple evaluation.  This may make a SAVE_EXPR.  */
+
+tree
+protect_multiple_eval (tree exp)
+{
+  tree type = TREE_TYPE (exp);
+
+  /* If EXP has no side effects, we theoritically don't need to do anything.
+     However, we may be recursively passed more and more complex expressions
+     involving checks which will be reused multiple times and eventually be
+     unshared for gimplification; in order to avoid a complexity explosion
+     at that point, we protect any expressions more complex than a simple
+     arithmetic expression.  */
+  if (!TREE_SIDE_EFFECTS (exp)
+      && (CONSTANT_CLASS_P (exp)
+         || !EXPRESSION_CLASS_P (skip_simple_arithmetic (exp))))
+    return exp;
+
+  /* If this is a conversion, protect what's inside the conversion.
+     Similarly, if we're indirectly referencing something, we only
+     need to protect the address since the data itself can't change
+     in these situations.  */
+  if (TREE_CODE (exp) == NON_LVALUE_EXPR
+      || CONVERT_EXPR_P (exp)
+      || TREE_CODE (exp) == VIEW_CONVERT_EXPR
+      || TREE_CODE (exp) == INDIRECT_REF
+      || TREE_CODE (exp) == UNCONSTRAINED_ARRAY_REF)
+  return build1 (TREE_CODE (exp), type,
+                protect_multiple_eval (TREE_OPERAND (exp, 0)));
+
+  /* If this is a fat pointer or something that can be placed in a register,
+     just make a SAVE_EXPR.  Likewise for a CALL_EXPR as large objects are
+     returned via invisible reference in most ABIs so the temporary will
+     directly be filled by the callee.  */
+  if (TYPE_IS_FAT_POINTER_P (type)
+      || TYPE_MODE (type) != BLKmode
+      || TREE_CODE (exp) == CALL_EXPR)
+    return save_expr (exp);
+
+  /* Otherwise reference, protect the address and dereference.  */
+  return
+    build_unary_op (INDIRECT_REF, type,
+                   save_expr (build_unary_op (ADDR_EXPR,
+                                              build_reference_type (type),
+                                              exp)));
+}
+\f
+/* This is equivalent to stabilize_reference in tree.c, but we know how to
+   handle our own nodes and we take extra arguments.  FORCE says whether to
+   force evaluation of everything.  We set SUCCESS to true unless we walk
+   through something we don't know how to stabilize.  */
+
+tree
+maybe_stabilize_reference (tree ref, bool force, bool *success)
+{
+  tree type = TREE_TYPE (ref);
+  enum tree_code code = TREE_CODE (ref);
+  tree result;
+
+  /* Assume we'll success unless proven otherwise.  */
+  *success = true;
+
+  switch (code)
+    {
+    case CONST_DECL:
+    case VAR_DECL:
+    case PARM_DECL:
+    case RESULT_DECL:
+      /* No action is needed in this case.  */
+      return ref;
+
+    case ADDR_EXPR:
+    CASE_CONVERT:
+    case FLOAT_EXPR:
+    case FIX_TRUNC_EXPR:
+    case VIEW_CONVERT_EXPR:
+      result
+       = build1 (code, type,
+                 maybe_stabilize_reference (TREE_OPERAND (ref, 0), force,
+                                            success));
+      break;
+
+    case INDIRECT_REF:
+    case UNCONSTRAINED_ARRAY_REF:
+      result = build1 (code, type,
+                      gnat_stabilize_reference_1 (TREE_OPERAND (ref, 0),
+                                                  force));
+      break;
+
+    case COMPONENT_REF:
+     result = build3 (COMPONENT_REF, type,
+                     maybe_stabilize_reference (TREE_OPERAND (ref, 0), force,
+                                                success),
+                     TREE_OPERAND (ref, 1), NULL_TREE);
+      break;
+
+    case BIT_FIELD_REF:
+      result = build3 (BIT_FIELD_REF, type,
+                      maybe_stabilize_reference (TREE_OPERAND (ref, 0), force,
+                                                 success),
+                      gnat_stabilize_reference_1 (TREE_OPERAND (ref, 1),
+                                                  force),
+                      gnat_stabilize_reference_1 (TREE_OPERAND (ref, 2),
+                                                  force));
+      break;
+
+    case ARRAY_REF:
+    case ARRAY_RANGE_REF:
+      result = build4 (code, type,
+                      maybe_stabilize_reference (TREE_OPERAND (ref, 0), force,
+                                                 success),
+                      gnat_stabilize_reference_1 (TREE_OPERAND (ref, 1),
+                                                  force),
+                      NULL_TREE, NULL_TREE);
+      break;
+
+    case CALL_EXPR:
+    case COMPOUND_EXPR:
+      result = gnat_stabilize_reference_1 (ref, force);
+      break;
+
+    case CONSTRUCTOR:
+      /* Constructors with 1 element are used extensively to formally
+        convert objects to special wrapping types.  */
+      if (TREE_CODE (type) == RECORD_TYPE
+         && VEC_length (constructor_elt, CONSTRUCTOR_ELTS (ref)) == 1)
+       {
+         tree index
+           = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (ref), 0)->index;
+         tree value
+           = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (ref), 0)->value;
+         result
+           = build_constructor_single (type, index,
+                                       gnat_stabilize_reference_1 (value,
+                                                                   force));
+       }
+      else
+       {
+         *success = false;
+         return ref;
+       }
+      break;
+
+    case ERROR_MARK:
+      ref = error_mark_node;
+
+      /* ...  fall through to failure ... */
+
+      /* If arg isn't a kind of lvalue we recognize, make no change.
+        Caller should recognize the error for an invalid lvalue.  */
+    default:
+      *success = false;
+      return ref;
+    }
+
+  TREE_READONLY (result) = TREE_READONLY (ref);
+
+  /* TREE_THIS_VOLATILE and TREE_SIDE_EFFECTS attached to the initial
+     expression may not be sustained across some paths, such as the way via
+     build1 for INDIRECT_REF.  We re-populate those flags here for the general
+     case, which is consistent with the GCC version of this routine.
+
+     Special care should be taken regarding TREE_SIDE_EFFECTS, because some
+     paths introduce side effects where there was none initially (e.g. calls
+     to save_expr), and we also want to keep track of that.  */
+
+  TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
+  TREE_SIDE_EFFECTS (result) |= TREE_SIDE_EFFECTS (ref);
+
+  return result;
+}
+
+/* Wrapper around maybe_stabilize_reference, for common uses without
+   lvalue restrictions and without need to examine the success
+   indication.  */
+
+static tree
+gnat_stabilize_reference (tree ref, bool force)
+{
+  bool dummy;
+  return maybe_stabilize_reference (ref, force, &dummy);
+}
+
+/* Similar to stabilize_reference_1 in tree.c, but supports an extra
+   arg to force a SAVE_EXPR for everything.  */
+
+static tree
+gnat_stabilize_reference_1 (tree e, bool force)
+{
+  enum tree_code code = TREE_CODE (e);
+  tree type = TREE_TYPE (e);
+  tree result;
+
+  /* We cannot ignore const expressions because it might be a reference
+     to a const array but whose index contains side-effects.  But we can
+     ignore things that are actual constant or that already have been
+     handled by this function.  */
+
+  if (TREE_CONSTANT (e) || code == SAVE_EXPR)
+    return e;
+
+  switch (TREE_CODE_CLASS (code))
+    {
+    case tcc_exceptional:
+    case tcc_type:
+    case tcc_declaration:
+    case tcc_comparison:
+    case tcc_statement:
+    case tcc_expression:
+    case tcc_reference:
+    case tcc_vl_exp:
+      /* If this is a COMPONENT_REF of a fat pointer, save the entire
+        fat pointer.  This may be more efficient, but will also allow
+        us to more easily find the match for the PLACEHOLDER_EXPR.  */
+      if (code == COMPONENT_REF
+         && TYPE_IS_FAT_POINTER_P (TREE_TYPE (TREE_OPERAND (e, 0))))
+       result = build3 (COMPONENT_REF, type,
+                        gnat_stabilize_reference_1 (TREE_OPERAND (e, 0),
+                                                    force),
+                        TREE_OPERAND (e, 1), TREE_OPERAND (e, 2));
+      else if (TREE_SIDE_EFFECTS (e) || force)
+       return save_expr (e);
+      else
+       return e;
+      break;
+
+    case tcc_constant:
+      /* Constants need no processing.  In fact, we should never reach
+        here.  */
+      return e;
+
+    case tcc_binary:
+      /* Recursively stabilize each operand.  */
+      result = build2 (code, type,
+                      gnat_stabilize_reference_1 (TREE_OPERAND (e, 0), force),
+                      gnat_stabilize_reference_1 (TREE_OPERAND (e, 1),
+                                                  force));
+      break;
+
+    case tcc_unary:
+      /* Recursively stabilize each operand.  */
+      result = build1 (code, type,
+                      gnat_stabilize_reference_1 (TREE_OPERAND (e, 0),
+                                                  force));
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
+
+  TREE_READONLY (result) = TREE_READONLY (e);
+
+  TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
+  TREE_SIDE_EFFECTS (result) |= TREE_SIDE_EFFECTS (e);
+  return result;
+}
+\f
 /* Convert SLOC into LOCUS.  Return true if SLOC corresponds to a source code
    location and false if it doesn't.  In the former case, set the Gigi global
    variable REF_FILENAME to the simple debug file name as given by sinput.  */