aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/utils2.c
diff options
context:
space:
mode:
authorGeert Bosch <bosch@gcc.gnu.org>2002-03-08 21:11:04 +0100
committerGeert Bosch <bosch@gcc.gnu.org>2002-03-08 21:11:04 +0100
commit07fc65c47c45af6439208797e1ab26f7daedb666 (patch)
treeb584a79288c93215b05fb451943291ccd039388b /gcc/ada/utils2.c
parent24965e7a8ac518b99a3bd7ef5b2d8d88f96bf514 (diff)
downloadgcc-07fc65c47c45af6439208797e1ab26f7daedb666.zip
gcc-07fc65c47c45af6439208797e1ab26f7daedb666.tar.gz
gcc-07fc65c47c45af6439208797e1ab26f7daedb666.tar.bz2
41intnam.ads, [...]: Merge in ACT changes.
* 41intnam.ads, 42intnam.ads, 4aintnam.ads, 4cintnam.ads, 4dintnam.ads, 4gintnam.ads, 4hintnam.ads, 4lintnam.ads, 4mintnam.ads, 4pintnam.ads, 4rintnam.ads, 4sintnam.ads, 4uintnam.ads, 4vcalend.adb, 4zintnam.ads, 52system.ads, 5amastop.adb, 5asystem.ads, 5ataprop.adb, 5atpopsp.adb, 5avxwork.ads, 5bosinte.adb, 5bsystem.ads, 5esystem.ads, 5fsystem.ads, 5ftaprop.adb, 5ginterr.adb, 5gmastop.adb, 5gsystem.ads, 5gtaprop.adb, 5gtasinf.adb, 5gtasinf.ads, 5hparame.ads, 5hsystem.ads, 5htaprop.adb, 5htraceb.adb, 5itaprop.adb, 5ksystem.ads, 5kvxwork.ads, 5lintman.adb, 5lsystem.ads, 5mvxwork.ads, 5ninmaop.adb, 5nosinte.ads, 5ntaprop.adb, 5ointerr.adb, 5omastop.adb, 5oosinte.adb, 5osystem.ads, 5otaprop.adb, 5otaspri.ads, 5pvxwork.ads, 5qtaprop.adb, 5sintman.adb, 5ssystem.ads, 5staprop.adb, 5stpopse.adb, 5svxwork.ads, 5tosinte.ads, 5uintman.adb, 5vasthan.adb, 5vinmaop.adb, 5vinterr.adb, 5vintman.adb, 5vmastop.adb, 5vparame.ads, 5vsystem.ads, 5vtaprop.adb, 5vtpopde.adb, 5wmemory.adb, 5wsystem.ads, 5wtaprop.adb, 5ysystem.ads, 5zinterr.adb, 5zintman.adb, 5zosinte.adb, 5zosinte.ads, 5zsystem.ads, 5ztaprop.adb, 6vcpp.adb, 6vcstrea.adb, 7sintman.adb, 7staprop.adb, 7stpopsp.adb, 9drpc.adb, Make-lang.in, Makefile.in, a-caldel.adb, a-comlin.ads, a-dynpri.adb, a-except.adb, a-except.ads, a-finali.adb, a-ncelfu.ads, a-reatim.adb, a-retide.adb, a-stream.ads, a-ststio.adb, a-ststio.ads, a-stwifi.adb, a-tags.adb, a-tasatt.adb, a-textio.adb, a-tideau.adb, a-tiflau.adb, a-tigeau.adb, a-tigeau.ads, a-tiinau.adb, a-timoau.adb, a-witeio.adb, a-wtdeau.adb, a-wtenau.adb, a-wtflau.adb, a-wtgeau.adb, a-wtgeau.ads, a-wtinau.adb, a-wtmoau.adb, ada-tree.def, ada-tree.h, adaint.c, adaint.h, ali-util.adb, ali.adb, ali.ads, atree.adb, atree.ads, atree.h, back_end.adb, bcheck.adb, bindgen.adb, bindusg.adb, checks.adb, comperr.adb, config-lang.in, csets.adb, csets.ads, cstand.adb, cstreams.c, debug.adb, debug.ads, decl.c, einfo.adb, einfo.ads, einfo.h, elists.h, errout.adb, errout.ads, eval_fat.adb, exp_aggr.adb, exp_attr.adb, exp_ch11.adb, exp_ch12.adb, exp_ch13.adb, exp_ch2.adb, exp_ch3.adb, exp_ch3.ads, exp_ch4.adb, exp_ch5.adb, exp_ch6.adb, exp_ch7.adb, exp_ch7.ads, exp_ch9.adb, exp_ch9.ads, exp_dbug.adb, exp_dbug.ads, exp_disp.ads, exp_dist.adb, exp_fixd.adb, exp_intr.adb, exp_pakd.adb, exp_prag.adb, exp_strm.adb, exp_util.adb, exp_util.ads, expander.adb, expect.c, fe.h, fmap.adb, fmap.ads, fname-uf.adb, freeze.adb, frontend.adb, g-awk.adb, g-cgideb.adb, g-comlin.adb, g-comlin.ads, g-debpoo.adb, g-dirope.adb, g-dirope.ads, g-dyntab.adb, g-expect.adb, g-expect.ads, g-io.ads, g-io_aux.adb, g-io_aux.ads, g-locfil.adb, g-locfil.ads, g-os_lib.adb, g-os_lib.ads, g-regexp.adb, g-regpat.adb, g-socket.adb, g-socket.ads, g-spipat.adb, g-table.adb, g-trasym.adb, g-trasym.ads, gigi.h, gmem.c, gnat1drv.adb, gnatbind.adb, gnatbl.c, gnatchop.adb, gnatcmd.adb, gnatdll.adb, gnatfind.adb, gnatlbr.adb, gnatlink.adb, gnatls.adb, gnatmem.adb, gnatprep.adb, gnatvsn.ads, gnatxref.adb, hlo.adb, hostparm.ads, i-cobol.adb, i-cpp.adb, i-cstrea.ads, i-cstrin.adb, i-pacdec.adb, i-vxwork.ads, impunit.adb, init.c, inline.adb, io-aux.c, layout.adb, lib-load.adb, lib-util.adb, lib-writ.adb, lib-writ.ads, lib-xref.adb, lib-xref.ads, lib.adb, lib.ads, make.adb, makeusg.adb, mdll.adb, memroot.adb, misc.c, mlib-tgt.adb, mlib-utl.adb, mlib-utl.ads, mlib.adb, namet.adb, namet.ads, namet.h, nlists.h, nmake.adb, nmake.ads, nmake.adt, opt.adb, opt.ads, osint.adb, osint.ads, output.adb, output.ads, par-ch2.adb, par-ch3.adb, par-ch5.adb, par-prag.adb, par-tchk.adb, par-util.adb, par.adb, prj-attr.adb, prj-dect.adb, prj-env.adb, prj-env.ads, prj-nmsc.adb, prj-part.adb, prj-proc.adb, prj-strt.adb, prj-tree.adb, prj-tree.ads, prj.adb, prj.ads, raise.c, raise.h, repinfo.adb, restrict.adb, restrict.ads, rident.ads, rtsfind.adb, rtsfind.ads, s-arit64.adb, s-asthan.adb, s-atacco.adb, s-atacco.ads, s-auxdec.adb, s-crc32.adb, s-crc32.ads, s-direio.adb, s-fatgen.adb, s-fileio.adb, s-finimp.adb, s-gloloc.adb, s-gloloc.ads, s-interr.adb, s-mastop.adb, s-mastop.ads, s-memory.adb, s-parame.ads, s-parint.adb, s-pooglo.adb, s-pooloc.adb, s-rpc.adb, s-secsta.adb, s-sequio.adb, s-shasto.adb, s-soflin.adb, s-soflin.ads, s-stache.adb, s-taasde.adb, s-taasde.ads, s-tadeca.adb, s-tadeca.ads, s-tadert.adb, s-tadert.ads, s-taenca.adb, s-taenca.ads, s-taprob.adb, s-taprop.ads, s-tarest.adb, s-tasdeb.adb, s-tasini.adb, s-tasini.ads, s-taskin.adb, s-taskin.ads, s-tasque.adb, s-tasque.ads, s-tasren.adb, s-tasren.ads, s-tassta.adb, s-tasuti.adb, s-tasuti.ads, s-tataat.adb, s-tataat.ads, s-tpoben.adb, s-tpoben.ads, s-tpobop.adb, s-tposen.adb, s-tposen.ads, s-traceb.adb, s-traceb.ads, s-unstyp.ads, s-widenu.adb, scn-nlit.adb, scn.adb, sem.adb, sem_aggr.adb, sem_attr.adb, sem_attr.ads, sem_case.adb, sem_ch10.adb, sem_ch11.adb, sem_ch11.ads, sem_ch12.adb, sem_ch13.adb, sem_ch13.ads, sem_ch2.adb, sem_ch3.adb, sem_ch3.ads, sem_ch4.adb, sem_ch5.adb, sem_ch6.adb, sem_ch6.ads, sem_ch7.adb, sem_ch8.adb, sem_ch8.ads, sem_ch9.adb, sem_disp.adb, sem_dist.adb, sem_elab.adb, sem_elim.adb, sem_elim.ads, sem_eval.adb, sem_intr.adb, sem_mech.adb, sem_prag.adb, sem_res.adb, sem_type.adb, sem_util.adb, sem_util.ads, sem_vfpt.adb, sem_warn.adb, sinfo.adb, sinfo.ads, sinfo.h, sinput-l.adb, sinput-l.ads, sinput.adb, sinput.ads, snames.adb, snames.ads, snames.h, sprint.adb, sprint.ads, stringt.adb, stringt.ads, stringt.h, style.adb, switch.adb, switch.ads, sysdep.c, system.ads, table.adb, targparm.adb, targparm.ads, targtyps.c, tbuild.adb, tbuild.ads, tracebak.c, trans.c, tree_gen.adb, tree_io.adb, treepr.adb, treepr.ads, treeprs.ads, treeprs.adt, ttypes.ads, types.adb, types.ads, types.h, uintp.ads, urealp.ads, usage.adb, utils.c, utils2.c, validsw.adb, xnmake.adb, xr_tabls.adb, xr_tabls.ads, xref_lib.adb, xref_lib.ads : Merge in ACT changes. * 1ssecsta.adb, 1ssecsta.ads, a-chlat9.ads, a-cwila9.ads, g-enblsp.adb, g-md5.adb, g-md5.ads, gnatname.adb, gnatname.ads, mkdir.c, osint-b.adb, osint-b.ads, osint-c.adb, osint-c.ads, osint-l.adb, osint-l.ads, osint-m.adb, osint-m.ads : New files * 3lsoccon.ads, 5qparame.ads, 5qvxwork.ads, 5smastop.adb, 5zparame.ads, gnatmain.adb, gnatmain.ads, gnatpsys.adb : Removed * mdllfile.adb, mdllfile.ads, mdlltool.adb, mdlltool.ads : Renamed to mdll-fil.ad[bs] and mdll-util.ad[bs] * mdll-fil.adb, mdll-fil.ads, mdll-utl.adb, mdll-utl.ads : Renamed from mdllfile.ad[bs] and mdlltool.ad[bs] From-SVN: r50451
Diffstat (limited to 'gcc/ada/utils2.c')
-rw-r--r--gcc/ada/utils2.c155
1 files changed, 79 insertions, 76 deletions
diff --git a/gcc/ada/utils2.c b/gcc/ada/utils2.c
index e9b5429..f681f1c 100644
--- a/gcc/ada/utils2.c
+++ b/gcc/ada/utils2.c
@@ -6,9 +6,9 @@
* *
* C Implementation File *
* *
- * $Revision: 1.3 $
+ * $Revision$
* *
- * Copyright (C) 1992-2001, Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2002, Free Software Foundation, Inc. *
* *
* GNAT is free software; you can redistribute it and/or modify it under *
* terms of the GNU General Public License as published by the Free Soft- *
@@ -233,7 +233,7 @@ contains_save_expr_p (exp)
case ADDR_EXPR: case INDIRECT_REF:
case COMPONENT_REF:
- case NOP_EXPR: case CONVERT_EXPR: case UNCHECKED_CONVERT_EXPR:
+ case NOP_EXPR: case CONVERT_EXPR: case VIEW_CONVERT_EXPR:
return contains_save_expr_p (TREE_OPERAND (exp, 0));
case CONSTRUCTOR:
@@ -446,7 +446,7 @@ compare_arrays (result_type, a1, a2)
result = build_binary_op (TRUTH_ANDIF_EXPR, result_type, result,
- build (EQ_EXPR, result_type, a1, a2));
+ fold (build (EQ_EXPR, result_type, a1, a2)));
}
@@ -647,7 +647,7 @@ build_binary_op (op_code, result_type, left_operand, right_operand)
unless we are not changing the mode. */
while ((TREE_CODE (left_operand) == CONVERT_EXPR
|| TREE_CODE (left_operand) == NOP_EXPR
- || TREE_CODE (left_operand) == UNCHECKED_CONVERT_EXPR)
+ || TREE_CODE (left_operand) == VIEW_CONVERT_EXPR)
&& (((INTEGRAL_TYPE_P (left_type)
|| POINTER_TYPE_P (left_type))
&& (INTEGRAL_TYPE_P (TREE_TYPE
@@ -680,20 +680,20 @@ build_binary_op (op_code, result_type, left_operand, right_operand)
/* If the RHS has a conversion between record and array types and
an inner type is no worse, use it. Note we cannot do this for
- modular types or types with TYPE_ALIGN_OK_P, since the latter
+ modular types or types with TYPE_ALIGN_OK, since the latter
might indicate a conversion between a root type and a class-wide
type, which we must not remove. */
- while (TREE_CODE (right_operand) == UNCHECKED_CONVERT_EXPR
+ while (TREE_CODE (right_operand) == VIEW_CONVERT_EXPR
&& ((TREE_CODE (right_type) == RECORD_TYPE
&& ! TYPE_LEFT_JUSTIFIED_MODULAR_P (right_type)
- && ! TYPE_ALIGN_OK_P (right_type)
+ && ! TYPE_ALIGN_OK (right_type)
&& ! TYPE_IS_FAT_POINTER_P (right_type))
|| TREE_CODE (right_type) == ARRAY_TYPE)
&& (((TREE_CODE (TREE_TYPE (TREE_OPERAND (right_operand, 0)))
== RECORD_TYPE)
&& ! (TYPE_LEFT_JUSTIFIED_MODULAR_P
(TREE_TYPE (TREE_OPERAND (right_operand, 0))))
- && ! (TYPE_ALIGN_OK_P
+ && ! (TYPE_ALIGN_OK
(TREE_TYPE (TREE_OPERAND (right_operand, 0))))
&& ! (TYPE_IS_FAT_POINTER_P
(TREE_TYPE (TREE_OPERAND (right_operand, 0)))))
@@ -719,32 +719,45 @@ build_binary_op (op_code, result_type, left_operand, right_operand)
operation_type = best_type;
/* If a class-wide type may be involved, force use of the RHS type. */
- if (TREE_CODE (right_type) == RECORD_TYPE
- && TYPE_ALIGN_OK_P (right_type))
+ if (TREE_CODE (right_type) == RECORD_TYPE && TYPE_ALIGN_OK (right_type))
operation_type = right_type;
- /* After we strip off any COMPONENT_REF, ARRAY_REF, or ARRAY_RANGE_REF
- from the lhs, we must have either an INDIRECT_REF or a decl. Allow
- UNCHECKED_CONVERT_EXPRs, but set TREE_ADDRESSABLE to show they are
- in an LHS. Finally, allow NOP_EXPR if both types are the same tree
- code and mode because we know these will be nops. */
- for (result = left_operand;
- TREE_CODE (result) == COMPONENT_REF
- || TREE_CODE (result) == ARRAY_REF
- || TREE_CODE (result) == ARRAY_RANGE_REF
- || TREE_CODE (result) == REALPART_EXPR
- || TREE_CODE (result) == IMAGPART_EXPR
- || TREE_CODE (result) == WITH_RECORD_EXPR
- || TREE_CODE (result) == UNCHECKED_CONVERT_EXPR
- || ((TREE_CODE (result) == NOP_EXPR
- || TREE_CODE (result) == CONVERT_EXPR)
- && (TREE_CODE (TREE_TYPE (result))
- == TREE_CODE (TREE_TYPE (TREE_OPERAND (result, 0))))
- && (TYPE_MODE (TREE_TYPE (TREE_OPERAND (result, 0)))
- == TYPE_MODE (TREE_TYPE (result))));
- result = TREE_OPERAND (result, 0))
- if (TREE_CODE (result) == UNCHECKED_CONVERT_EXPR)
- TREE_ADDRESSABLE (result) = 1;
+ /* Ensure everything on the LHS is valid. If we have a field reference,
+ strip anything that get_inner_reference can handle. Then remove any
+ conversions with type types having the same code and mode. Mark
+ VIEW_CONVERT_EXPRs with TREE_ADDRESSABLE. When done, we must have
+ either an INDIRECT_REF or a decl. */
+ result = left_operand;
+ while (1)
+ {
+ tree restype = TREE_TYPE (result);
+
+ if (TREE_CODE (result) == COMPONENT_REF
+ || TREE_CODE (result) == ARRAY_REF
+ || TREE_CODE (result) == ARRAY_RANGE_REF)
+ while (handled_component_p (result))
+ result = TREE_OPERAND (result, 0);
+ else if (TREE_CODE (result) == REALPART_EXPR
+ || TREE_CODE (result) == IMAGPART_EXPR
+ || TREE_CODE (result) == WITH_RECORD_EXPR
+ || ((TREE_CODE (result) == NOP_EXPR
+ || TREE_CODE (result) == CONVERT_EXPR)
+ && (((TREE_CODE (restype)
+ == TREE_CODE (TREE_TYPE
+ (TREE_OPERAND (result, 0))))
+ && (TYPE_MODE (TREE_TYPE
+ (TREE_OPERAND (result, 0)))
+ == TYPE_MODE (restype)))
+ || TYPE_ALIGN_OK (restype))))
+ result = TREE_OPERAND (result, 0);
+ else if (TREE_CODE (result) == VIEW_CONVERT_EXPR)
+ {
+ TREE_ADDRESSABLE (result) = 1;
+ result = TREE_OPERAND (result, 0);
+ }
+ else
+ break;
+ }
if (TREE_CODE (result) != INDIRECT_REF && TREE_CODE (result) != NULL_EXPR
&& ! DECL_P (result))
@@ -807,17 +820,6 @@ build_binary_op (op_code, result_type, left_operand, right_operand)
|| op_code == ARRAY_RANGE_REF)
mark_addressable (left_operand);
- /* If the array is an UNCHECKED_CONVERT_EXPR from and to BLKmode
- types, convert it to a normal conversion since GCC can deal
- with any mis-alignment as part of the handling of compponent
- references. */
-
- if (TREE_CODE (left_operand) == UNCHECKED_CONVERT_EXPR
- && TYPE_MODE (TREE_TYPE (left_operand)) == BLKmode
- && TYPE_MODE (TREE_TYPE (TREE_OPERAND (left_operand, 0))) == BLKmode)
- left_operand = build1 (CONVERT_EXPR, TREE_TYPE (left_operand),
- TREE_OPERAND (left_operand, 0));
-
modulus = 0;
break;
@@ -865,20 +867,6 @@ build_binary_op (op_code, result_type, left_operand, right_operand)
right_base_type = get_base_type (right_type);
}
- /* If either object if an UNCHECKED_CONVERT_EXPR between two BLKmode
- objects, change it to a CONVERT_EXPR. */
- if (TREE_CODE (left_operand) == UNCHECKED_CONVERT_EXPR
- && TYPE_MODE (left_type) == BLKmode
- && TYPE_MODE (TREE_TYPE (TREE_OPERAND (left_operand, 0))) == BLKmode)
- left_operand = build1 (CONVERT_EXPR, left_type,
- TREE_OPERAND (left_operand, 0));
- if (TREE_CODE (right_operand) == UNCHECKED_CONVERT_EXPR
- && TYPE_MODE (right_type) == BLKmode
- && (TYPE_MODE (TREE_TYPE (TREE_OPERAND (right_operand, 0)))
- == BLKmode))
- right_operand = build1 (CONVERT_EXPR, right_type,
- TREE_OPERAND (right_operand, 0));
-
/* If both objects are arrays, compare them specially. */
if ((TREE_CODE (left_type) == ARRAY_TYPE
|| (TREE_CODE (left_type) == INTEGER_TYPE
@@ -1058,8 +1046,8 @@ build_binary_op (op_code, result_type, left_operand, right_operand)
TREE_SIDE_EFFECTS (result) |= has_side_effects;
TREE_CONSTANT (result)
- = (TREE_CONSTANT (left_operand) & TREE_CONSTANT (right_operand)
- && op_code != ARRAY_REF && op_code != ARRAY_RANGE_REF);
+ |= (TREE_CONSTANT (left_operand) & TREE_CONSTANT (right_operand)
+ && op_code != ARRAY_REF && op_code != ARRAY_RANGE_REF);
if ((op_code == ARRAY_REF || op_code == ARRAY_RANGE_REF)
&& TYPE_VOLATILE (operation_type))
@@ -1183,6 +1171,11 @@ build_unary_op (op_code, result_type, operand)
if (offset == 0)
offset = size_zero_node;
+ if (bitpos % BITS_PER_UNIT != 0)
+ post_error
+ ("taking address of object not aligned on storage unit?",
+ error_gnat_node);
+
offset = size_binop (PLUS_EXPR, offset,
size_int (bitpos / BITS_PER_UNIT));
@@ -1415,7 +1408,25 @@ build_cond_expr (result_type, condition_operand, true_operand, false_operand)
result = fold (build (COND_EXPR, result_type, condition_operand,
true_operand, false_operand));
- if (addr_p)
+
+ /* If either operand is a SAVE_EXPR (possibly surrounded by
+ arithmetic, make sure it gets done. */
+ while (TREE_CODE_CLASS (TREE_CODE (true_operand)) == '1'
+ || (TREE_CODE_CLASS (TREE_CODE (true_operand)) == '2'
+ && TREE_CONSTANT (TREE_OPERAND (true_operand, 1))))
+ true_operand = TREE_OPERAND (true_operand, 0);
+
+ while (TREE_CODE_CLASS (TREE_CODE (false_operand)) == '1'
+ || (TREE_CODE_CLASS (TREE_CODE (false_operand)) == '2'
+ && TREE_CONSTANT (TREE_OPERAND (false_operand, 1))))
+ false_operand = TREE_OPERAND (false_operand, 0);
+
+ if (TREE_CODE (true_operand) == SAVE_EXPR)
+ result = build (COMPOUND_EXPR, result_type, true_operand, result);
+ if (TREE_CODE (false_operand) == SAVE_EXPR)
+ result = build (COMPOUND_EXPR, result_type, false_operand, result);
+
+ if (addr_p)
result = build_unary_op (INDIRECT_REF, NULL_TREE, result);
return result;
@@ -1475,13 +1486,14 @@ build_call_0_expr (fundecl)
return call;
}
-/* Call a function FCN that raises an exception and pass the line
- number and file name, if requested. */
+/* Call a function that raises an exception and pass the line number and file
+ name, if requested. MSG says which exception function to call. */
tree
-build_call_raise (fndecl)
- tree fndecl;
+build_call_raise (msg)
+ int msg;
{
+ tree fndecl = gnat_raise_decls[msg];
const char *str = discard_file_names ? "" : ref_filename;
int len = strlen (str) + 1;
tree filename = build_string (len, str);
@@ -1641,15 +1653,6 @@ build_simple_component_ref (record_variable, component, field)
if (field == 0)
return 0;
- /* If the record variable is an UNCHECKED_CONVERT_EXPR from and to BLKmode
- types, convert it to a normal conversion since GCC can deal with any
- mis-alignment as part of the handling of compponent references. */
- if (TREE_CODE (record_variable) == UNCHECKED_CONVERT_EXPR
- && TYPE_MODE (TREE_TYPE (record_variable)) == BLKmode
- && TYPE_MODE (TREE_TYPE (TREE_OPERAND (record_variable, 0))) == BLKmode)
- record_variable = build1 (CONVERT_EXPR, TREE_TYPE (record_variable),
- TREE_OPERAND (record_variable, 0));
-
/* It would be nice to call "fold" here, but that can lose a type
we need to tag a PLACEHOLDER_EXPR with, so we can't do it. */
ref = build (COMPONENT_REF, TREE_TYPE (field), record_variable, field);
@@ -1683,7 +1686,7 @@ build_component_ref (record_variable, component, field)
else if (field != 0)
return build1 (NULL_EXPR, TREE_TYPE (field),
- build_call_raise (raise_constraint_error_decl));
+ build_call_raise (CE_Discriminant_Check_Failed));
else
gigi_abort (512);
}
@@ -1861,7 +1864,7 @@ build_allocator (type, init, result_type, gnat_proc, gnat_pool)
storage = build_call_alloc_dealloc (NULL_TREE, size,
TYPE_ALIGN (storage_type),
gnat_proc, gnat_pool);
- storage = convert (storage_ptr_type, make_save_expr (storage));
+ storage = convert (storage_ptr_type, protect_multiple_eval (storage));
if (TREE_CODE (type) == RECORD_TYPE && TYPE_IS_PADDING_P (type))
{