aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-expr.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2005-04-29 17:31:39 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2005-04-29 17:31:39 +0200
commitd198b59ab12557edbafc2bba595f855caccfc6ec (patch)
treed2859b3b62d8719bdc1d462cb30cdea8235bea87 /gcc/fortran/trans-expr.c
parentbe12e697e42187347dffea36e37db82cf04d37a5 (diff)
downloadgcc-d198b59ab12557edbafc2bba595f855caccfc6ec.zip
gcc-d198b59ab12557edbafc2bba595f855caccfc6ec.tar.gz
gcc-d198b59ab12557edbafc2bba595f855caccfc6ec.tar.bz2
[multiple changes]
2005-04-29 Jakub Jelinek <jakub@redhat.com> PR fortran/13082 PR fortran/18824 * trans-expr.c (gfc_conv_variable): Handle return values in functions with alternate entry points. * resolve.c (resolve_entries): Remove unnecessary string termination after snprintf. Set result of entry master. If all entries have the same type, set entry master's type to that common type, otherwise set mixed_entry_master attribute. * trans-types.c (gfc_get_mixed_entry_union): New function. (gfc_get_function_type): Use it for mixed_entry_master functions. * gfortran.h (symbol_attribute): Add mixed_entry_master bit. * decl.c (gfc_match_entry): Set entry->result properly for function ENTRY. * trans-decl.c (gfc_get_symbol_decl): For entry_master, skip over __entry argument. (build_entry_thunks): Handle return values in entry thunks. Clear BT_CHARACTER's ts.cl->backend_decl, so that it is not shared between multiple contexts. (gfc_get_fake_result_decl): Use DECL_ARGUMENTS from current_function_decl instead of sym->backend_decl. Skip over entry master's entry id argument. For mixed_entry_master entries or their results, return a COMPONENT_REF of the fake result. (gfc_trans_deferred_vars): Don't warn about missing return value if at least one entry point uses RESULT. (gfc_generate_function_code): For entry master returning CHARACTER, copy ts.cl->backend_decl to all entry result syms. * trans-array.c (gfc_trans_dummy_array_bias): Don't consider return values optional just because they are in entry master. * gfortran.dg/entry_4.f90: New test. * gfortran.fortran-torture/execute/entry_1.f90: New test. * gfortran.fortran-torture/execute/entry_2.f90: New test. * gfortran.fortran-torture/execute/entry_3.f90: New test. * gfortran.fortran-torture/execute/entry_4.f90: New test. * gfortran.fortran-torture/execute/entry_5.f90: New test. * gfortran.fortran-torture/execute/entry_6.f90: New test. * gfortran.fortran-torture/execute/entry_7.f90: New test. 2005-04-29 Tobias Schl"uter <tobias.schlueter@physik.uni-muenchen.de> * gfortran.fortran-torture/execute/entry_8.f90: New test. From-SVN: r98993
Diffstat (limited to 'gcc/fortran/trans-expr.c')
-rw-r--r--gcc/fortran/trans-expr.c44
1 files changed, 34 insertions, 10 deletions
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 58a0d6e..caf3d75 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -309,11 +309,43 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr)
}
else
{
+ tree se_expr = NULL_TREE;
+
se->expr = gfc_get_symbol_decl (sym);
+ /* Special case for assigning the return value of a function.
+ Self recursive functions must have an explicit return value. */
+ if (se->expr == current_function_decl && sym->attr.function
+ && (sym->result == sym))
+ se_expr = gfc_get_fake_result_decl (sym);
+
+ /* Similarly for alternate entry points. */
+ else if (sym->attr.function && sym->attr.entry
+ && (sym->result == sym)
+ && sym->ns->proc_name->backend_decl == current_function_decl)
+ {
+ gfc_entry_list *el = NULL;
+
+ for (el = sym->ns->entries; el; el = el->next)
+ if (sym == el->sym)
+ {
+ se_expr = gfc_get_fake_result_decl (sym);
+ break;
+ }
+ }
+
+ else if (sym->attr.result
+ && sym->ns->proc_name->backend_decl == current_function_decl
+ && sym->ns->proc_name->attr.entry_master
+ && !gfc_return_by_reference (sym->ns->proc_name))
+ se_expr = gfc_get_fake_result_decl (sym);
+
+ if (se_expr)
+ se->expr = se_expr;
+
/* Procedure actual arguments. */
- if (sym->attr.flavor == FL_PROCEDURE
- && se->expr != current_function_decl)
+ else if (sym->attr.flavor == FL_PROCEDURE
+ && se->expr != current_function_decl)
{
gcc_assert (se->want_pointer);
if (!sym->attr.dummy)
@@ -324,14 +356,6 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr)
return;
}
- /* Special case for assigning the return value of a function.
- Self recursive functions must have an explicit return value. */
- if (se->expr == current_function_decl && sym->attr.function
- && (sym->result == sym))
- {
- se->expr = gfc_get_fake_result_decl (sym);
- }
-
/* Dereference scalar dummy variables. */
if (sym->attr.dummy
&& sym->ts.type != BT_CHARACTER