aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface
diff options
context:
space:
mode:
authorMarc Poulhiès <poulhies@adacore.com>2023-04-03 16:36:13 +0200
committerMarc Poulhiès <poulhies@adacore.com>2023-05-30 09:12:18 +0200
commit203dece1e9d061582f34009907c048be628e960d (patch)
treed954ebedb287f0d32014379a05e4cfd2315a7004 /gcc/ada/gcc-interface
parent0a769b29ee0beef9998f7694894b6c8f5aa93e6a (diff)
downloadgcc-203dece1e9d061582f34009907c048be628e960d.zip
gcc-203dece1e9d061582f34009907c048be628e960d.tar.gz
gcc-203dece1e9d061582f34009907c048be628e960d.tar.bz2
ada: Fix incorrect copies being used with 'Address
When using 'Address on an object with a size clause, gigi would end up creating a copy and using its address instead of the one of the original object, leading to incorrect behavior. Remove the conversion (that triggers the copy) when 'Address is applied to a declaration. gcc/ada/ * gcc-interface/trans.cc (Attribute_to_gnu): Also strip conversion in case of DECL.
Diffstat (limited to 'gcc/ada/gcc-interface')
-rw-r--r--gcc/ada/gcc-interface/trans.cc13
1 files changed, 9 insertions, 4 deletions
diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc
index 1c3c6c0..57933ce 100644
--- a/gcc/ada/gcc-interface/trans.cc
+++ b/gcc/ada/gcc-interface/trans.cc
@@ -1714,12 +1714,17 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
case Attr_Address:
case Attr_Unrestricted_Access:
/* Conversions don't change the address of references but can cause
- build_unary_op to miss the references below, so strip them off.
+ build_unary_op to miss the references below so strip them off.
+
+ Also remove the conversions applied to declarations as the intent is
+ to take the decls' address, not that of the copies that the
+ conversions may create.
+
On the contrary, if the address-of operation causes a temporary
to be created, then it must be created with the proper type. */
gnu_expr = remove_conversions (gnu_prefix,
!Must_Be_Byte_Aligned (gnat_node));
- if (REFERENCE_CLASS_P (gnu_expr))
+ if (REFERENCE_CLASS_P (gnu_expr) || DECL_P (gnu_expr))
gnu_prefix = gnu_expr;
/* If we are taking 'Address of an unconstrained object, this is the
@@ -4575,7 +4580,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target,
/* The FUNCTION_TYPE node giving the GCC type of the subprogram. */
tree gnu_subprog_type = TREE_TYPE (gnu_subprog);
/* The return type of the FUNCTION_TYPE. */
- tree gnu_result_type;;
+ tree gnu_result_type;
const bool frontend_builtin
= (TREE_CODE (gnu_subprog) == FUNCTION_DECL
&& DECL_BUILT_IN_CLASS (gnu_subprog) == BUILT_IN_FRONTEND);
@@ -4657,7 +4662,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target,
}
/* We must elaborate the entire profile now because, if it references types
- that were initially incomplete,, their elaboration changes the contents
+ that were initially incomplete, their elaboration changes the contents
of GNU_SUBPROG_TYPE and, in particular, may change the result type. */
elaborate_profile (gnat_formal, gnat_result_type);