mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-28 15:45:56 +08:00
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
This commit is contained in:
parent
6058b2fa2c
commit
552725e3bd
@ -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>
|
2005-09-16 Laurent GUERBY <laurent@guerby.net>
|
||||||
|
|
||||||
PR ada/23788
|
PR ada/23788
|
||||||
|
@ -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,
|
extern tree build_cond_expr (tree result_type, tree condition_operand,
|
||||||
tree true_operand, tree false_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
|
/* Build a CALL_EXPR to call FUNDECL with one argument, ARG. Return
|
||||||
the CALL_EXPR. */
|
the CALL_EXPR. */
|
||||||
extern tree build_call_1_expr (tree fundecl, tree arg);
|
extern tree build_call_1_expr (tree fundecl, tree arg);
|
||||||
|
@ -1456,9 +1456,7 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
|
|||||||
gnu_retval = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_retval);
|
gnu_retval = build_unary_op (INDIRECT_REF, NULL_TREE, gnu_retval);
|
||||||
|
|
||||||
add_stmt_with_node
|
add_stmt_with_node
|
||||||
(build1 (RETURN_EXPR, void_type_node,
|
(build_return_expr (DECL_RESULT (current_function_decl), gnu_retval),
|
||||||
build2 (MODIFY_EXPR, TREE_TYPE (gnu_retval),
|
|
||||||
DECL_RESULT (current_function_decl), gnu_retval)),
|
|
||||||
gnat_node);
|
gnat_node);
|
||||||
gnat_poplevel ();
|
gnat_poplevel ();
|
||||||
gnu_result = end_stmt_group ();
|
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. */
|
/* Set up to move the copy back to the original. */
|
||||||
gnu_temp = build2 (MODIFY_EXPR, TREE_TYPE (gnu_copy),
|
gnu_temp = build_binary_op (MODIFY_EXPR, NULL_TREE,
|
||||||
gnu_copy, gnu_actual);
|
gnu_copy, gnu_actual);
|
||||||
annotate_with_node (gnu_temp, gnat_actual);
|
annotate_with_node (gnu_temp, gnat_actual);
|
||||||
append_to_statement_list (gnu_temp, &gnu_after_list);
|
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;
|
tree gnu_ret_val = NULL_TREE;
|
||||||
/* The place to put the return value. */
|
/* The place to put the return value. */
|
||||||
tree gnu_lhs;
|
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
|
/* 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
|
parameters passed by copy in copy out, we need to return a record
|
||||||
@ -3626,18 +3622,20 @@ gnat_to_gnu (Node_Id gnat_node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (gnu_ret_val)
|
/* If the Ada subprogram is a regular procedure, just return. */
|
||||||
gnu_result = build2 (MODIFY_EXPR, TREE_TYPE (gnu_ret_val),
|
gnu_lhs = NULL_TREE;
|
||||||
gnu_lhs, gnu_ret_val);
|
|
||||||
|
|
||||||
if (TYPE_RETURNS_BY_TARGET_PTR_P (gnu_subprog_type))
|
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);
|
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;
|
break;
|
||||||
|
|
||||||
|
@ -1378,8 +1378,50 @@ build_cond_expr (tree result_type, tree condition_operand,
|
|||||||
|
|
||||||
return result;
|
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
|
/* Build a CALL_EXPR to call FUNDECL with one argument, ARG. Return
|
||||||
the CALL_EXPR. */
|
the CALL_EXPR. */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user