aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/trans.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@gcc.gnu.org>2020-05-25 09:18:03 +0200
committerEric Botcazou <ebotcazou@gcc.gnu.org>2020-05-25 09:25:57 +0200
commit5dce843f32edfd998ae4844d8115a9c9b9c394bc (patch)
treea8057058326d856b8ee25828bb2fa8e40e7192f6 /gcc/ada/gcc-interface/trans.c
parent94c0409717bf8bf783963c1d50bb8f4a4732dce7 (diff)
downloadgcc-5dce843f32edfd998ae4844d8115a9c9b9c394bc.zip
gcc-5dce843f32edfd998ae4844d8115a9c9b9c394bc.tar.gz
gcc-5dce843f32edfd998ae4844d8115a9c9b9c394bc.tar.bz2
Fix wrong assignment to mutable Out parameter of task entry
Under very specific circumstances the compiler can generate a wrong assignment to a mutable record object which contains an array component, because it does not correctly handle the update of the discriminant. gcc/ada/ChangeLog * gcc-interface/gigi.h (operand_type): New static inline function. * gcc-interface/trans.c (gnat_to_gnu): Do not suppress conversion to the resulty type at the end for array types. * gcc-interface/utils2.c (build_binary_op) <MODIFY_EXPR>: Do not remove conversions between array types on the LHS. gcc/testsuite/ChangeLog * gnat.dg/array39.adb: New test. * gnat.dg/array39_pkg.ads: New helper. * gnat.dg/array39_pkg.adb: Likewise.
Diffstat (limited to 'gcc/ada/gcc-interface/trans.c')
-rw-r--r--gcc/ada/gcc-interface/trans.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index b7a4cad..969a480 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -8821,7 +8821,8 @@ gnat_to_gnu (Node_Id gnat_node)
1. If this is the LHS of an assignment or an actual parameter of a
call, return the result almost unmodified since the RHS will have
to be converted to our type in that case, unless the result type
- has a simpler size. Likewise if there is just a no-op unchecked
+ has a simpler size or for array types because this size might be
+ changed in-between. Likewise if there is just a no-op unchecked
conversion in-between. Similarly, don't convert integral types
that are the operands of an unchecked conversion since we need
to ignore those conversions (for 'Valid).
@@ -8856,15 +8857,17 @@ gnat_to_gnu (Node_Id gnat_node)
&& !AGGREGATE_TYPE_P (TREE_TYPE (gnu_result))))
&& !(TYPE_SIZE (gnu_result_type)
&& TYPE_SIZE (TREE_TYPE (gnu_result))
- && (AGGREGATE_TYPE_P (gnu_result_type)
- == AGGREGATE_TYPE_P (TREE_TYPE (gnu_result)))
+ && AGGREGATE_TYPE_P (gnu_result_type)
+ == AGGREGATE_TYPE_P (TREE_TYPE (gnu_result))
&& ((TREE_CODE (TYPE_SIZE (gnu_result_type)) == INTEGER_CST
&& (TREE_CODE (TYPE_SIZE (TREE_TYPE (gnu_result)))
!= INTEGER_CST))
|| (TREE_CODE (TYPE_SIZE (gnu_result_type)) != INTEGER_CST
&& !CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_result_type))
&& (CONTAINS_PLACEHOLDER_P
- (TYPE_SIZE (TREE_TYPE (gnu_result))))))
+ (TYPE_SIZE (TREE_TYPE (gnu_result)))))
+ || (TREE_CODE (gnu_result_type) == ARRAY_TYPE
+ && TREE_CODE (TREE_TYPE (gnu_result)) == ARRAY_TYPE))
&& !(TREE_CODE (gnu_result_type) == RECORD_TYPE
&& TYPE_JUSTIFIED_MODULAR_P (gnu_result_type))))
{