diff options
author | Daniel Kraft <d@domob.eu> | 2008-11-24 14:10:37 +0100 |
---|---|---|
committer | Daniel Kraft <domob@gcc.gnu.org> | 2008-11-24 14:10:37 +0100 |
commit | a03826d1d56e819d6e6d0bd2ce96d96a931dc370 (patch) | |
tree | 6d3d651ee55170c647ffb5c2494dd04d553c5f08 /gcc/fortran/resolve.c | |
parent | 72a2609f5d7421ab10d04b06f10e78814b0370cc (diff) | |
download | gcc-a03826d1d56e819d6e6d0bd2ce96d96a931dc370.zip gcc-a03826d1d56e819d6e6d0bd2ce96d96a931dc370.tar.gz gcc-a03826d1d56e819d6e6d0bd2ce96d96a931dc370.tar.bz2 |
re PR fortran/37779 (Missing RECURSIVE not detected)
2008-11-24 Daniel Kraft <d@domob.eu>
PR fortran/37779
* resolve.c (resolve_procedure_expression): New method.
(resolve_variable): Call it.
(resolve_actual_arglist): Call gfc_resolve_expr for procedure arguments.
2008-11-24 Daniel Kraft <d@domob.eu>
PR fortran/37779
* gfortran.dg/c_funloc_tests.f03: Added missing `RECURSIVE'.
* gfortran.dg/c_funloc_tests_2.f03: Ditto.
* gfortran.dg/recursive_check_4.f03: New test.
* gfortran.dg/recursive_check_5.f03: New test.
From-SVN: r142158
Diffstat (limited to 'gcc/fortran/resolve.c')
-rw-r--r-- | gcc/fortran/resolve.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 0f0644f..f1c27e6 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -1072,6 +1072,33 @@ count_specific_procs (gfc_expr *e) return n; } + +/* Resolve a procedure expression, like passing it to a called procedure or as + RHS for a procedure pointer assignment. */ + +static gfc_try +resolve_procedure_expression (gfc_expr* expr) +{ + gfc_symbol* sym; + + if (expr->ts.type != BT_PROCEDURE || expr->expr_type != EXPR_VARIABLE) + return SUCCESS; + gcc_assert (expr->symtree); + sym = expr->symtree->n.sym; + gcc_assert (sym->attr.flavor == FL_PROCEDURE); + + /* A non-RECURSIVE procedure that is used as procedure expression within its + own body is in danger of being called recursively. */ + if (!sym->attr.recursive && sym == gfc_current_ns->proc_name + && !gfc_option.flag_recursive) + gfc_warning ("Non-RECURSIVE procedure '%s' at %L is possibly calling" + " itself recursively. Declare it RECURSIVE or use" + " -frecursive", sym->name, &expr->where); + + return SUCCESS; +} + + /* Resolve an actual argument list. Most of the time, this is just resolving the expressions in the list. The exception is that we sometimes have to decide whether arguments @@ -1180,8 +1207,8 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype, && sym->ns == gfc_current_ns && !sym->ns->entries->sym->attr.recursive) { - gfc_error ("Reference to ENTRY '%s' at %L is recursive, but procedure " - "'%s' is not declared as RECURSIVE", + gfc_error ("Reference to ENTRY '%s' at %L is recursive, but" + " procedure '%s' is not declared as RECURSIVE", sym->name, &e->where, sym->ns->entries->sym->name); } @@ -1211,6 +1238,9 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype, sym->attr.intrinsic = 1; sym->attr.function = 1; } + + if (gfc_resolve_expr (e) == FAILURE) + return FAILURE; goto argument_list; } @@ -1235,6 +1265,8 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype, || sym->attr.intrinsic || sym->attr.external) { + if (gfc_resolve_expr (e) == FAILURE) + return FAILURE; goto argument_list; } @@ -4155,7 +4187,7 @@ resolve_variable (gfc_expr *e) if (sym->attr.flavor == FL_PROCEDURE && !sym->attr.function) { e->ts.type = BT_PROCEDURE; - return SUCCESS; + goto resolve_procedure; } if (sym->ts.type != BT_UNKNOWN) @@ -4237,6 +4269,10 @@ resolve_variable (gfc_expr *e) sym->entry_id = current_entry_id + 1; } +resolve_procedure: + if (t == SUCCESS && resolve_procedure_expression (e) == FAILURE) + t = FAILURE; + return t; } |