diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2005-10-21 15:46:19 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2005-10-21 15:46:19 +0000 |
commit | 552725e3bd542d98dd0f4a830c602230fff7138c (patch) | |
tree | 6f247edb01a5d6b87e8e3c910f200eaeb6643429 /gcc | |
parent | 6058b2fa2cc5799e442cc8c7a02bff0b170b6025 (diff) | |
download | gcc-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/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/ada/gigi.h | 3 | ||||
-rw-r--r-- | gcc/ada/trans.c | 24 | ||||
-rw-r--r-- | gcc/ada/utils2.c | 44 |
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. */ |