diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-04-29 17:31:39 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-04-29 17:31:39 +0200 |
commit | d198b59ab12557edbafc2bba595f855caccfc6ec (patch) | |
tree | d2859b3b62d8719bdc1d462cb30cdea8235bea87 /gcc/fortran/trans-expr.c | |
parent | be12e697e42187347dffea36e37db82cf04d37a5 (diff) | |
download | gcc-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.c | 44 |
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 |