summaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2010-04-08 20:16:36 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2010-04-08 20:16:36 +0000
commit4cd5bb613c816cf996ca11a356cff1c7870806b0 (patch)
tree3bbe3665b3ad0f65e64b4973b9c1ddee13f15d9a /gcc/function.c
parentfd731bfb1dfe0d6b125b85c784f353228b242f09 (diff)
downloadgcc-4cd5bb613c816cf996ca11a356cff1c7870806b0.tar.gz
* tree.h (TREE_ADDRESSABLE): Document its effect for function types.
* calls.c (expand_call): Pass the function type to aggregate_value_p. * function.c (aggregate_value_p): Do not honor DECL_BY_REFERENCE on the target function of a CALL_EXPR. Honor TREE_ADDRESSABLE on the function type instead. Reorder and simplify checks. * gimplify.c (gimplify_modify_expr_rhs) <WITH_SIZE_EXPR>: New case. ada/ * gcc-interface/ada-tree.h (TYPE_RETURNS_UNCONSTRAINED_P): Rename into. (TYPE_RETURN_UNCONSTRAINED_P): ...this. (TYPE_RETURNS_BY_REF_P): Rename into. (TYPE_RETURN_BY_DIRECT_REF_P): ...this. (TYPE_RETURNS_BY_TARGET_PTR_P): Delete. * gcc-interface/gigi.h (create_subprog_type): Adjust parameter names. (build_return_expr): Likewise. * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Subprogram_Type>: Rename local variables. If the return Mechanism is By_Reference, pass return_by_invisible_ref_p to create_subprog_type instead of toggling TREE_ADDRESSABLE. Test return_by_invisible_ref_p in order to annotate the mechanism. Use regular return for contrained types with non-static size and return by invisible reference for unconstrained return types with default discriminants. Update comment. * gcc-interface/trans.c (Subprogram_Body_to_gnu): If the function returns by invisible reference, turn the RESULT_DECL into a pointer. Do not handle DECL_BY_REF_P in the CICO case here. (call_to_gnu): Remove code handling return by target pointer. For a function call, if the return type has non-constant size, generate the assignment with an INIT_EXPR. (gnat_to_gnu) <N_Return_Statement>: Remove dead code in the CICO case. If the function returns by invisible reference, build the copy return operation manually. (add_decl_expr): Initialize the variable with an INIT_EXPR. * gcc-interface/utils.c (create_subprog_type): Adjust parameter names. Adjust for renaming of macros. Copy the node only when necessary. (create_subprog_decl): Do not toggle TREE_ADDRESSABLE on the return type, only change DECL_BY_REFERENCE on the RETURN_DECL. (convert_from_reference): Delete. (is_byref_result): Likewise. (gnat_genericize_r): Likewise. (gnat_genericize): Likewise. (end_subprog_body): Do not call gnat_genericize. * gcc-interface/utils2.c (build_binary_op) <INIT_EXPR>: New case. (build_return_expr): Adjust parameter names, logic and comment. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158139 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c45
1 files changed, 19 insertions, 26 deletions
diff --git a/gcc/function.c b/gcc/function.c
index 60a429dc2b5..21cbb527391 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -1853,41 +1853,36 @@ struct rtl_opt_pass pass_instantiate_virtual_regs =
int
aggregate_value_p (const_tree exp, const_tree fntype)
{
+ const_tree type = (TYPE_P (exp)) ? exp : TREE_TYPE (exp);
int i, regno, nregs;
rtx reg;
- const_tree type = (TYPE_P (exp)) ? exp : TREE_TYPE (exp);
-
- /* DECL node associated with FNTYPE when relevant, which we might need to
- check for by-invisible-reference returns, typically for CALL_EXPR input
- EXPressions. */
- const_tree fndecl = NULL_TREE;
-
if (fntype)
switch (TREE_CODE (fntype))
{
case CALL_EXPR:
- fndecl = get_callee_fndecl (fntype);
- fntype = (fndecl
- ? TREE_TYPE (fndecl)
- : TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (fntype))));
+ {
+ tree fndecl = get_callee_fndecl (fntype);
+ fntype = (fndecl
+ ? TREE_TYPE (fndecl)
+ : TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (fntype))));
+ }
break;
case FUNCTION_DECL:
- fndecl = fntype;
- fntype = TREE_TYPE (fndecl);
+ fntype = TREE_TYPE (fntype);
break;
case FUNCTION_TYPE:
case METHOD_TYPE:
break;
case IDENTIFIER_NODE:
- fntype = 0;
+ fntype = NULL_TREE;
break;
default:
- /* We don't expect other rtl types here. */
+ /* We don't expect other tree types here. */
gcc_unreachable ();
}
- if (TREE_CODE (type) == VOID_TYPE)
+ if (VOID_TYPE_P (type))
return 0;
/* If a record should be passed the same as its first (and only) member
@@ -1901,24 +1896,21 @@ aggregate_value_p (const_tree exp, const_tree fntype)
&& DECL_BY_REFERENCE (exp))
return 1;
- /* If the EXPression is a CALL_EXPR, honor DECL_BY_REFERENCE set on the
- called function RESULT_DECL, meaning the function returns in memory by
- invisible reference. This check lets front-ends not set TREE_ADDRESSABLE
- on the function type, which used to be the way to request such a return
- mechanism but might now be causing troubles at gimplification time if
- temporaries with the function type need to be created. */
- if (TREE_CODE (exp) == CALL_EXPR && fndecl && DECL_RESULT (fndecl)
- && DECL_BY_REFERENCE (DECL_RESULT (fndecl)))
+ /* Function types that are TREE_ADDRESSABLE force return in memory. */
+ if (fntype && TREE_ADDRESSABLE (fntype))
return 1;
- if (targetm.calls.return_in_memory (type, fntype))
- return 1;
/* Types that are TREE_ADDRESSABLE must be constructed in memory,
and thus can't be returned in registers. */
if (TREE_ADDRESSABLE (type))
return 1;
+
if (flag_pcc_struct_return && AGGREGATE_TYPE_P (type))
return 1;
+
+ if (targetm.calls.return_in_memory (type, fntype))
+ return 1;
+
/* Make sure we have suitable call-clobbered regs to return
the value in; if not, we must return it in memory. */
reg = hard_function_value (type, 0, fntype, 0);
@@ -1933,6 +1925,7 @@ aggregate_value_p (const_tree exp, const_tree fntype)
for (i = 0; i < nregs; i++)
if (! call_used_regs[regno + i])
return 1;
+
return 0;
}