aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2005-10-21 15:46:19 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2005-10-21 15:46:19 +0000
commit552725e3bd542d98dd0f4a830c602230fff7138c (patch)
tree6f247edb01a5d6b87e8e3c910f200eaeb6643429 /gcc
parent6058b2fa2cc5799e442cc8c7a02bff0b170b6025 (diff)
downloadgcc-552725e3bd542d98dd0f4a830c602230fff7138c.zip
gcc-552725e3bd542d98dd0f4a830c602230fff7138c.tar.gz
gcc-552725e3bd542d98dd0f4a830c602230fff7138c.tar.bz2
re PR ada/21937 (Member record alignment triggers an ICE)
PR ada/21937 PR ada/22328 PR ada/22381 PR ada/22383 PR ada/22419 PR ada/22420 * utils2.c (build_return_expr): New helper function. * gigi.h (build_return_expr): Declare it. * trans.c (Subprogram_Body_to_gnu): Use build_return_expr instead of manually building the RETURN_EXPR tree. (call_to_gnu): Pass MODIFY_EXPR through build_binary_op. (gnat_to_gnu) <N_Return_Statement>: Pass MODIFY_EXPR through build_binary_op for the "target pointer" case. ᅵUse build_return_expr instead of manually building the RETURN_EXPR tree. From-SVN: r105741
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/ChangeLog17
-rw-r--r--gcc/ada/gigi.h3
-rw-r--r--gcc/ada/trans.c24
-rw-r--r--gcc/ada/utils2.c44
4 files changed, 74 insertions, 14 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 2a99275..877d6b7 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,20 @@
+2005-10-21 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/21937
+ PR ada/22328
+ PR ada/22381
+ PR ada/22383
+ PR ada/22419
+ PR ada/22420
+ * utils2.c (build_return_expr): New helper function.
+ * gigi.h (build_return_expr): Declare it.
+ * trans.c (Subprogram_Body_to_gnu): Use build_return_expr instead
+ of manually building the RETURN_EXPR tree.
+ (call_to_gnu): Pass MODIFY_EXPR through build_binary_op.
+ (gnat_to_gnu) <N_Return_Statement>: Pass MODIFY_EXPR through
+ build_binary_op for the "target pointer" case.  Use build_return_expr
+ instead of manually building the RETURN_EXPR tree.
+
2005-09-16 Laurent GUERBY <laurent@guerby.net>
PR ada/23788
diff --git a/gcc/ada/gigi.h b/gcc/ada/gigi.h
index 0adf644..9dba805 100644
--- a/gcc/ada/gigi.h
+++ b/gcc/ada/gigi.h
@@ -678,6 +678,9 @@ extern tree build_unary_op (enum tree_code op_code, tree result_type,
extern tree build_cond_expr (tree result_type, tree condition_operand,
tree true_operand, tree false_operand);
+/* Similar, but for RETURN_EXPR. */
+extern tree build_return_expr (tree result_decl, tree ret_val);
+
/* Build a CALL_EXPR to call FUNDECL with one argument, ARG. Return
the CALL_EXPR. */
extern tree build_call_1_expr (tree fundecl, tree arg);
diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c
index fb741a3..0e05b6d 100644
--- a/gcc/ada/trans.c
+++ b/gcc/ada/trans.c
@@ -1456,9 +1456,7 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
gnu_retval = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_retval);
add_stmt_with_node
- (build1 (RETURN_EXPR, void_type_node,
- build2 (MODIFY_EXPR, TREE_TYPE (gnu_retval),
- DECL_RESULT (current_function_decl), gnu_retval)),
+ (build_return_expr (DECL_RESULT (current_function_decl), gnu_retval),
gnat_node);
gnat_poplevel ();
gnu_result = end_stmt_group ();
@@ -1685,8 +1683,8 @@ call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target)
}
/* Set up to move the copy back to the original. */
- gnu_temp = build2 (MODIFY_EXPR, TREE_TYPE (gnu_copy),
- gnu_copy, gnu_actual);
+ gnu_temp = build_binary_op (MODIFY_EXPR, NULL_TREE,
+ gnu_copy, gnu_actual);
annotate_with_node (gnu_temp, gnat_actual);
append_to_statement_list (gnu_temp, &gnu_after_list);
}
@@ -3519,8 +3517,6 @@ gnat_to_gnu (Node_Id gnat_node)
tree gnu_ret_val = NULL_TREE;
/* The place to put the return value. */
tree gnu_lhs;
- /* Avoid passing error_mark_node to RETURN_EXPR. */
- gnu_result = NULL_TREE;
/* If we are dealing with a "return;" from an Ada procedure with
parameters passed by copy in copy out, we need to return a record
@@ -3626,18 +3622,20 @@ gnat_to_gnu (Node_Id gnat_node)
}
}
}
-
- if (gnu_ret_val)
- gnu_result = build2 (MODIFY_EXPR, TREE_TYPE (gnu_ret_val),
- gnu_lhs, gnu_ret_val);
+ else
+ /* If the Ada subprogram is a regular procedure, just return. */
+ gnu_lhs = NULL_TREE;
if (TYPE_RETURNS_BY_TARGET_PTR_P (gnu_subprog_type))
{
+ if (gnu_ret_val)
+ gnu_result = build_binary_op (MODIFY_EXPR, NULL_TREE,
+ gnu_lhs, gnu_ret_val);
add_stmt_with_node (gnu_result, gnat_node);
- gnu_result = NULL_TREE;
+ gnu_lhs = NULL_TREE;
}
- gnu_result = build1 (RETURN_EXPR, void_type_node, gnu_result);
+ gnu_result = build_return_expr (gnu_lhs, gnu_ret_val);
}
break;
diff --git a/gcc/ada/utils2.c b/gcc/ada/utils2.c
index 5847910..21a3f61 100644
--- a/gcc/ada/utils2.c
+++ b/gcc/ada/utils2.c
@@ -1378,8 +1378,50 @@ build_cond_expr (tree result_type, tree condition_operand,
return result;
}
-
+/* Similar, but for RETURN_EXPR. If RESULT_DECL is non-zero, build
+ a RETURN_EXPR around the assignment of RET_VAL to RESULT_DECL.
+ If RESULT_DECL is zero, build a bare RETURN_EXPR. */
+
+tree
+build_return_expr (tree result_decl, tree ret_val)
+{
+ tree result_expr;
+
+ if (result_decl)
+ {
+ /* The gimplifier explicitly enforces the following invariant:
+
+ RETURN_EXPR
+ |
+ MODIFY_EXPR
+ / \
+ / \
+ RESULT_DECL ...
+
+ As a consequence, type-homogeneity dictates that we use the type
+ of the RESULT_DECL as the operation type. */
+
+ tree operation_type = TREE_TYPE (result_decl);
+
+ /* Convert the right operand to the operation type. Note that
+ it's the same transformation as in the MODIFY_EXPR case of
+ build_binary_op with the additional guarantee that the type
+ cannot involve a placeholder, since otherwise the function
+ would use the "target pointer" return mechanism. */
+
+ if (operation_type != TREE_TYPE (ret_val))
+ ret_val = convert (operation_type, ret_val);
+
+ result_expr
+ = build2 (MODIFY_EXPR, operation_type, result_decl, ret_val);
+ }
+ else
+ result_expr = NULL_TREE;
+
+ return build1 (RETURN_EXPR, void_type_node, result_expr);
+}
+
/* Build a CALL_EXPR to call FUNDECL with one argument, ARG. Return
the CALL_EXPR. */