aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/trans.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2018-09-26 09:16:49 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2018-09-26 09:16:49 +0000
commit3b9d159401751981118415b472dd0bdb68e862f6 (patch)
tree784b824f3eb73fef6ee98fbc3e7a2dfbfbd4f130 /gcc/ada/gcc-interface/trans.c
parent1ac984f5952c52f0f70e64f5ab7a99fa62877df7 (diff)
downloadgcc-3b9d159401751981118415b472dd0bdb68e862f6.zip
gcc-3b9d159401751981118415b472dd0bdb68e862f6.tar.gz
gcc-3b9d159401751981118415b472dd0bdb68e862f6.tar.bz2
[Ada] Wrong handling of address clause for limited record type
2018-09-26 Eric Botcazou <ebotcazou@adacore.com> gcc/ada/ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Adjust code retrieving the address when a clause has already been processed. * gcc-interface/trans.c (gnat_to_gnu) <N_Attribute_Definition_Clause>: For an object with a Freeze node, build a meaningful expression. gcc/testsuite/ * gnat.dg/addr12.adb, gnat.dg/addr12_a.adb, gnat.dg/addr12_a.ads, gnat.dg/addr12_b.adb, gnat.dg/addr12_b.ads, gnat.dg/addr12_c.ads: New testcase. From-SVN: r264606
Diffstat (limited to 'gcc/ada/gcc-interface/trans.c')
-rw-r--r--gcc/ada/gcc-interface/trans.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 940bf5f..3e129b6 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -7570,13 +7570,33 @@ gnat_to_gnu (Node_Id gnat_node)
/* And we only deal with 'Address if the object has a Freeze node. */
gnat_temp = Entity (Name (gnat_node));
- if (No (Freeze_Node (gnat_temp)))
- break;
+ if (Freeze_Node (gnat_temp))
+ {
+ tree gnu_address = gnat_to_gnu (Expression (gnat_node));
+
+ /* Get the value to use as the address and save it as the equivalent
+ for the object; when it is frozen, gnat_to_gnu_entity will do the
+ right thing. For a subprogram, put the naked address but build a
+ meaningfull expression for an object in case its address is taken
+ before the Freeze node is encountered; this can happen if the type
+ of the object is limited and it is initialized with the result of
+ a function call. */
+ if (Is_Subprogram (gnat_temp))
+ gnu_result = gnu_address;
+ else
+ {
+ tree gnu_type = gnat_to_gnu_type (Etype (gnat_temp));
+ /* Drop atomic and volatile qualifiers for the expression. */
+ gnu_type = TYPE_MAIN_VARIANT (gnu_type);
+ gnu_type
+ = build_reference_type_for_mode (gnu_type, ptr_mode, true);
+ gnu_address = convert (gnu_type, gnu_address);
+ gnu_result
+ = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_address);
+ }
- /* Get the value to use as the address and save it as the equivalent
- for the object. When it is frozen, gnat_to_gnu_entity will do the
- right thing. */
- save_gnu_tree (gnat_temp, gnat_to_gnu (Expression (gnat_node)), true);
+ save_gnu_tree (gnat_temp, gnu_result, true);
+ }
break;
case N_Enumeration_Representation_Clause: