Commit 2d71b918 by Janus Weil

re PR fortran/42048 ([F03] Erroneous syntax error message on TBP call)

2009-11-26  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/42048
	PR fortran/42167
	* gfortran.h (gfc_is_function_return_value): New prototype.
	* match.c (gfc_match_call): Use new function
	'gfc_is_function_return_value'.
	* primary.c (gfc_is_function_return_value): New function to check if a
	symbol is the return value of an encompassing function.
	(match_actual_arg,gfc_match_rvalue,match_variable): Use new function
	'gfc_is_function_return_value'.
	* resolve.c (resolve_common_blocks,resolve_actual_arglist): Ditto.

2009-11-26  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/42048
	PR fortran/42167
	* gfortran.dg/select_type_10.f03: New test case.
	* gfortran.dg/typebound_call_11.f03: Extended test case.

From-SVN: r154679
parent 90dcfecb
2009-11-26 Janus Weil <janus@gcc.gnu.org>
PR fortran/42048
PR fortran/42167
* gfortran.h (gfc_is_function_return_value): New prototype.
* match.c (gfc_match_call): Use new function
'gfc_is_function_return_value'.
* primary.c (gfc_is_function_return_value): New function to check if a
symbol is the return value of an encompassing function.
(match_actual_arg,gfc_match_rvalue,match_variable): Use new function
'gfc_is_function_return_value'.
* resolve.c (resolve_common_blocks,resolve_actual_arglist): Ditto.
2009-11-25 Jakub Jelinek <jakub@redhat.com> 2009-11-25 Jakub Jelinek <jakub@redhat.com>
PR fortran/42162 PR fortran/42162
......
...@@ -2751,6 +2751,7 @@ symbol_attribute gfc_expr_attr (gfc_expr *); ...@@ -2751,6 +2751,7 @@ symbol_attribute gfc_expr_attr (gfc_expr *);
match gfc_match_rvalue (gfc_expr **); match gfc_match_rvalue (gfc_expr **);
match gfc_match_varspec (gfc_expr*, int, bool, bool); match gfc_match_varspec (gfc_expr*, int, bool, bool);
int gfc_check_digit (char, int); int gfc_check_digit (char, int);
bool gfc_is_function_return_value (gfc_symbol *, gfc_namespace *);
/* trans.c */ /* trans.c */
void gfc_generate_code (gfc_namespace *); void gfc_generate_code (gfc_namespace *);
......
...@@ -2975,7 +2975,8 @@ gfc_match_call (void) ...@@ -2975,7 +2975,8 @@ gfc_match_call (void)
/* If this is a variable of derived-type, it probably starts a type-bound /* If this is a variable of derived-type, it probably starts a type-bound
procedure call. */ procedure call. */
if ((sym->attr.flavor != FL_PROCEDURE || sym == gfc_current_ns->proc_name) if ((sym->attr.flavor != FL_PROCEDURE
|| gfc_is_function_return_value (sym, gfc_current_ns))
&& (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)) && (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS))
return match_typebound_call (st); return match_typebound_call (st);
......
...@@ -1347,6 +1347,25 @@ gfc_match_literal_constant (gfc_expr **result, int signflag) ...@@ -1347,6 +1347,25 @@ gfc_match_literal_constant (gfc_expr **result, int signflag)
} }
/* This checks if a symbol is the return value of an encompassing function.
Function nesting can be maximally two levels deep, but we may have
additional local namespaces like BLOCK etc. */
bool
gfc_is_function_return_value (gfc_symbol *sym, gfc_namespace *ns)
{
if (!sym->attr.function || (sym->result != sym))
return false;
while (ns)
{
if (ns->proc_name == sym)
return true;
ns = ns->parent;
}
return false;
}
/* Match a single actual argument value. An actual argument is /* Match a single actual argument value. An actual argument is
usually an expression, but can also be a procedure name. If the usually an expression, but can also be a procedure name. If the
argument is a single name, it is not always possible to tell argument is a single name, it is not always possible to tell
...@@ -1415,9 +1434,7 @@ match_actual_arg (gfc_expr **result) ...@@ -1415,9 +1434,7 @@ match_actual_arg (gfc_expr **result)
is being defined, then we have a variable. */ is being defined, then we have a variable. */
if (sym->attr.function && sym->result == sym) if (sym->attr.function && sym->result == sym)
{ {
if (gfc_current_ns->proc_name == sym if (gfc_is_function_return_value (sym, gfc_current_ns))
|| (gfc_current_ns->parent != NULL
&& gfc_current_ns->parent->proc_name == sym))
break; break;
if (sym->attr.entry if (sym->attr.entry
...@@ -2521,9 +2538,7 @@ gfc_match_rvalue (gfc_expr **result) ...@@ -2521,9 +2538,7 @@ gfc_match_rvalue (gfc_expr **result)
return MATCH_ERROR; return MATCH_ERROR;
} }
if (gfc_current_ns->proc_name == sym if (gfc_is_function_return_value (sym, gfc_current_ns))
|| (gfc_current_ns->parent != NULL
&& gfc_current_ns->parent->proc_name == sym))
goto variable; goto variable;
if (sym->attr.entry if (sym->attr.entry
...@@ -2998,10 +3013,7 @@ match_variable (gfc_expr **result, int equiv_flag, int host_flag) ...@@ -2998,10 +3013,7 @@ match_variable (gfc_expr **result, int equiv_flag, int host_flag)
if (sym->attr.function if (sym->attr.function
&& !sym->attr.external && !sym->attr.external
&& sym->result == sym && sym->result == sym
&& ((sym == gfc_current_ns->proc_name && (gfc_is_function_return_value (sym, gfc_current_ns)
&& sym == gfc_current_ns->proc_name->result)
|| (gfc_current_ns->parent
&& sym == gfc_current_ns->parent->proc_name->result)
|| (sym->attr.entry || (sym->attr.entry
&& sym->ns == gfc_current_ns) && sym->ns == gfc_current_ns)
|| (sym->attr.entry || (sym->attr.entry
......
...@@ -776,7 +776,7 @@ resolve_common_blocks (gfc_symtree *common_root) ...@@ -776,7 +776,7 @@ resolve_common_blocks (gfc_symtree *common_root)
gfc_error ("COMMON block '%s' at %L is also an intrinsic procedure", gfc_error ("COMMON block '%s' at %L is also an intrinsic procedure",
sym->name, &common_root->n.common->where); sym->name, &common_root->n.common->where);
else if (sym->attr.result else if (sym->attr.result
||(sym->attr.function && gfc_current_ns->proc_name == sym)) || gfc_is_function_return_value (sym, gfc_current_ns))
gfc_notify_std (GFC_STD_F2003, "Fortran 2003: COMMON block '%s' at %L " gfc_notify_std (GFC_STD_F2003, "Fortran 2003: COMMON block '%s' at %L "
"that is also a function result", sym->name, "that is also a function result", sym->name,
&common_root->n.common->where); &common_root->n.common->where);
...@@ -1400,10 +1400,7 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype, ...@@ -1400,10 +1400,7 @@ resolve_actual_arglist (gfc_actual_arglist *arg, procedure_type ptype,
/* If the symbol is the function that names the current (or /* If the symbol is the function that names the current (or
parent) scope, then we really have a variable reference. */ parent) scope, then we really have a variable reference. */
if (sym->attr.function && sym->result == sym if (gfc_is_function_return_value (sym, sym->ns))
&& (sym->ns->proc_name == sym
|| (sym->ns->parent != NULL
&& sym->ns->parent->proc_name == sym)))
goto got_variable; goto got_variable;
/* If all else fails, see if we have a specific intrinsic. */ /* If all else fails, see if we have a specific intrinsic. */
......
2009-11-26 Janus Weil <janus@gcc.gnu.org>
PR fortran/42048
PR fortran/42167
* gfortran.dg/select_type_10.f03: New test case.
* gfortran.dg/typebound_call_11.f03: Extended test case.
2009-11-26 Michael Matz <matz@suse.de> 2009-11-26 Michael Matz <matz@suse.de>
PR tree-optimization/41905 PR tree-optimization/41905
......
! { dg-do compile }
!
! PR 42167: [OOP] SELECT TYPE with function return value
!
! Contributed by Damian Rouson <damian@rouson.net>
module bar_module
implicit none
type :: bar
real ,dimension(:) ,allocatable :: f
contains
procedure :: total
end type
contains
function total(lhs,rhs)
class(bar) ,intent(in) :: lhs
class(bar) ,intent(in) :: rhs
class(bar) ,pointer :: total
select type(rhs)
type is (bar)
allocate(bar :: total)
select type(total)
type is (bar)
total%f = lhs%f + rhs%f
end select
end select
end function
end module
! { dg-final { cleanup-modules "bar_module" } }
...@@ -35,6 +35,14 @@ contains ...@@ -35,6 +35,14 @@ contains
call new%mesh%new_grid() call new%mesh%new_grid()
end function end function
type(field) function new_field3()
call g()
contains
subroutine g()
call new_field3%mesh%new_grid()
end subroutine g
end function new_field3
end module end module
! { dg-final { cleanup-modules "grid_module field_module" } } ! { dg-final { cleanup-modules "grid_module field_module" } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment