aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/trans.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/trans.c')
-rw-r--r--gcc/ada/trans.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c
index 2fafd48de8e..68ebacc735c 100644
--- a/gcc/ada/trans.c
+++ b/gcc/ada/trans.c
@@ -21,7 +21,7 @@
* MA 02111-1307, USA. *
* *
* GNAT was originally developed by the GNAT team at New York University. *
- * It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). *
+ * Extensive contributions were provided by Ada Core Technologies Inc. *
* *
****************************************************************************/
@@ -88,6 +88,10 @@ tree gnu_block_stack;
handler. Not used in the zero-cost case. */
static GTY(()) tree gnu_except_ptr_stack;
+/* List of TREE_LIST nodes containing pending elaborations lists.
+ used to prevent the elaborations being reclaimed by GC. */
+static GTY(()) tree gnu_pending_elaboration_lists;
+
/* Map GNAT tree codes to GCC tree codes for simple expressions. */
static enum tree_code gnu_codes[Number_Node_Kinds];
@@ -576,11 +580,13 @@ tree_transform (gnat_node)
gigi_abort (336);
else
- gnu_result
- = build_real (gnu_result_type,
- REAL_VALUE_LDEXP
- (TREE_REAL_CST (gnu_result),
- - UI_To_Int (Denominator (ur_realval))));
+ {
+ REAL_VALUE_TYPE tmp;
+
+ real_ldexp (&tmp, &TREE_REAL_CST (gnu_result),
+ - UI_To_Int (Denominator (ur_realval)));
+ gnu_result = build_real (gnu_result_type, tmp);
+ }
}
/* Now see if we need to negate the result. Do it this way to
@@ -5296,6 +5302,10 @@ build_unit_elab (gnat_unit, body_p, gnu_elab_list)
if (gnu_elab_list == 0)
return 1;
+ /* Prevent the elaboration list from being reclaimed by the GC. */
+ gnu_pending_elaboration_lists = chainon (gnu_pending_elaboration_lists,
+ gnu_elab_list);
+
/* Set our file and line number to that of the object and set up the
elaboration routine. */
gnu_decl = create_subprog_decl (create_concat_name (gnat_unit,
@@ -5356,6 +5366,9 @@ build_unit_elab (gnat_unit, body_p, gnu_elab_list)
gnu_block_stack = TREE_CHAIN (gnu_block_stack);
end_subprog_body ();
+ /* We are finished with the elaboration list it can now be discarded. */
+ gnu_pending_elaboration_lists = TREE_CHAIN (gnu_pending_elaboration_lists);
+
/* If there were no insns, we don't need an elab routine. It would
be nice to not output this one, but there's no good way to do that. */
return result;