Commit 9914f8cf by Paul Thomas

re PR fortran/20896 (ambiguous interface not detected)

2006-12-27  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/20896
	* interface.c (check_sym_interfaces): Try to resolve interface
	reference as a global symbol, if it is not a nodule procedure.
	(compare_actual_formal): Remove call to gfc_find_symbol; if
	the expression is already a variable it is locally declared
	and this has precedence.
	gfortran.h : Add prototype for resolve_global_procedure.
	resolve.c (resolve_global_procedure): Remove static attribute
	from function declaration.
	(resolve_fl_procedure): Remove symtree declaration and the
	redundant check for an ambiguous procedure.

	PR fortran/25135
	* module.c (load_generic_interfaces): If the symbol is present
	and is not generic it is ambiguous.

2006-12-27  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/20896
	* gfortran.dg/interface_10.f90: New test.
	* gfortran.dg/dummy_procedure_1.f90: Add error for call s1(z),
	since z is already, locally a variable.

	PR fortran/25135
	* gfortran.dg/generic_11.f90: New test.
	* gfortran.dg/interface_7.f90: Remove name clash between module
	name and procedure 'x' referenced in the interface.

From-SVN: r120218
parent 223da521
2006-12-27 Paul Thomas <pault@gcc.gnu.org>
PR fortran/20896
* interface.c (check_sym_interfaces): Try to resolve interface
reference as a global symbol, if it is not a nodule procedure.
(compare_actual_formal): Remove call to gfc_find_symbol; if
the expression is already a variable it is locally declared
and this has precedence.
gfortran.h : Add prototype for resolve_global_procedure.
resolve.c (resolve_global_procedure): Remove static attribute
from function declaration.
(resolve_fl_procedure): Remove symtree declaration and the
redundant check for an ambiguous procedure.
PR fortran/25135
* module.c (load_generic_interfaces): If the symbol is present
and is not generic it is ambiguous.
2006-12-22 Paul Thomas <pault@gcc.gnu.org> 2006-12-22 Paul Thomas <pault@gcc.gnu.org>
PR fortran/25818 PR fortran/25818
......
...@@ -2032,6 +2032,7 @@ void gfc_free_statement (gfc_code *); ...@@ -2032,6 +2032,7 @@ void gfc_free_statement (gfc_code *);
void gfc_free_statements (gfc_code *); void gfc_free_statements (gfc_code *);
/* resolve.c */ /* resolve.c */
void resolve_global_procedure (gfc_symbol *, locus *, int);
try gfc_resolve_expr (gfc_expr *); try gfc_resolve_expr (gfc_expr *);
void gfc_resolve (gfc_namespace *); void gfc_resolve (gfc_namespace *);
void gfc_resolve_blocks (gfc_code *, gfc_namespace *); void gfc_resolve_blocks (gfc_code *, gfc_namespace *);
......
...@@ -1016,6 +1016,11 @@ check_sym_interfaces (gfc_symbol * sym) ...@@ -1016,6 +1016,11 @@ check_sym_interfaces (gfc_symbol * sym)
if (sym->ns != gfc_current_ns) if (sym->ns != gfc_current_ns)
return; return;
if (sym->attr.if_source == IFSRC_IFBODY
&& sym->attr.flavor == FL_PROCEDURE
&& !sym->attr.mod_proc)
resolve_global_procedure (sym, &sym->declared_at, sym->attr.subroutine);
if (sym->generic != NULL) if (sym->generic != NULL)
{ {
sprintf (interface_name, "generic interface '%s'", sym->name); sprintf (interface_name, "generic interface '%s'", sym->name);
...@@ -1371,16 +1376,10 @@ compare_actual_formal (gfc_actual_arglist ** ap, ...@@ -1371,16 +1376,10 @@ compare_actual_formal (gfc_actual_arglist ** ap,
&& a->expr->expr_type == EXPR_VARIABLE && a->expr->expr_type == EXPR_VARIABLE
&& f->sym->attr.flavor == FL_PROCEDURE) && f->sym->attr.flavor == FL_PROCEDURE)
{ {
gsym = gfc_find_gsymbol (gfc_gsym_root, if (where)
a->expr->symtree->n.sym->name); gfc_error ("Expected a procedure for argument '%s' at %L",
if (gsym == NULL || (gsym->type != GSYM_FUNCTION f->sym->name, &a->expr->where);
&& gsym->type != GSYM_SUBROUTINE)) return 0;
{
if (where)
gfc_error ("Expected a procedure for argument '%s' at %L",
f->sym->name, &a->expr->where);
return 0;
}
} }
if (f->sym->attr.flavor == FL_PROCEDURE if (f->sym->attr.flavor == FL_PROCEDURE
......
...@@ -3090,6 +3090,16 @@ load_generic_interfaces (void) ...@@ -3090,6 +3090,16 @@ load_generic_interfaces (void)
sym->attr.generic = 1; sym->attr.generic = 1;
sym->attr.use_assoc = 1; sym->attr.use_assoc = 1;
} }
else
{
/* Unless sym is a generic interface, this reference
is ambiguous. */
gfc_symtree *st;
p = p ? p : name;
st = gfc_find_symtree (gfc_current_ns->sym_root, p);
st->ambiguous = sym->attr.generic ? 0 : 1;
}
if (i == 1) if (i == 1)
{ {
mio_interface_rest (&sym->generic); mio_interface_rest (&sym->generic);
......
...@@ -1156,7 +1156,7 @@ find_noncopying_intrinsics (gfc_symbol * fnsym, gfc_actual_arglist * actual) ...@@ -1156,7 +1156,7 @@ find_noncopying_intrinsics (gfc_symbol * fnsym, gfc_actual_arglist * actual)
reference. The corresponding code that is called in creating reference. The corresponding code that is called in creating
global entities is parse.c. */ global entities is parse.c. */
static void void
resolve_global_procedure (gfc_symbol *sym, locus *where, int sub) resolve_global_procedure (gfc_symbol *sym, locus *where, int sub)
{ {
gfc_gsymbol * gsym; gfc_gsymbol * gsym;
...@@ -5560,7 +5560,6 @@ static try ...@@ -5560,7 +5560,6 @@ static try
resolve_fl_procedure (gfc_symbol *sym, int mp_flag) resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
{ {
gfc_formal_arglist *arg; gfc_formal_arglist *arg;
gfc_symtree *st;
if (sym->attr.ambiguous_interfaces && !sym->attr.referenced) if (sym->attr.ambiguous_interfaces && !sym->attr.referenced)
gfc_warning ("Although not referenced, '%s' at %L has ambiguous " gfc_warning ("Although not referenced, '%s' at %L has ambiguous "
...@@ -5570,16 +5569,6 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag) ...@@ -5570,16 +5569,6 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
&& resolve_fl_var_and_proc (sym, mp_flag) == FAILURE) && resolve_fl_var_and_proc (sym, mp_flag) == FAILURE)
return FAILURE; return FAILURE;
st = gfc_find_symtree (gfc_current_ns->sym_root, sym->name);
if (st && st->ambiguous
&& sym->attr.referenced
&& !sym->attr.generic)
{
gfc_error ("Procedure %s at %L is ambiguous",
sym->name, &sym->declared_at);
return FAILURE;
}
if (sym->ts.type == BT_CHARACTER) if (sym->ts.type == BT_CHARACTER)
{ {
gfc_charlen *cl = sym->ts.cl; gfc_charlen *cl = sym->ts.cl;
......
2006-12-27 Paul Thomas <pault@gcc.gnu.org>
PR fortran/20896
* gfortran.dg/interface_10.f90: New test.
* gfortran.dg/dummy_procedure_1.f90: Add error for call s1(z),
since z is already, locally a variable.
PR fortran/25135
* gfortran.dg/generic_11.f90: New test.
* gfortran.dg/interface_7.f90: Remove name clash between module
name and procedure 'x' referenced in the interface.
2006-12-23 Manuel Lopez-Ibanez <manu@gcc.gnu.org> 2006-12-23 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR middle-end/7651 PR middle-end/7651
...@@ -37,7 +37,7 @@ end module m1 ...@@ -37,7 +37,7 @@ end module m1
call s1(w) ! { dg-error "not allowed as an actual argument" } call s1(w) ! { dg-error "not allowed as an actual argument" }
call s1(x) ! explicit interface call s1(x) ! explicit interface
call s1(y) ! declared external call s1(y) ! declared external
call s1(z) ! already compiled call s1(z) ! { dg-error "Expected a procedure for argument" }
contains contains
integer function w() integer function w()
w = 1 w = 1
......
! { dg-do compile }
! Test the fix for PR25135 in which the ambiguity between subroutine
! foo in m_foo and interface foo in m_bar was not recognised.
!
!Contributed by Yusuke IGUCHI <iguchi@coral.t.u-tokyo.ac.jp>
!
module m_foo
contains
subroutine foo
print *, "foo"
end subroutine
end module
module m_bar
interface foo
module procedure bar
end interface
contains
subroutine bar
print *, "bar"
end subroutine
end module
use m_foo
use m_bar
call foo ! { dg-error "is an ambiguous reference" }
end
! { dg-final { cleanup-modules "m_foo m_bar" } }
! { dg-do compile }
! Test the fix for PR20896 in which the ambiguous use
! of p was not detected.
!
! Contributed by Joost VandeVondele <jv244@cam.ac.uk>
!
INTERFACE g
SUBROUTINE s1(p) ! { dg-error "is already being used" }
INTERFACE
SUBROUTINE p
END
END INTERFACE
END
SUBROUTINE s2(p) ! { dg-error "Global name" }
INTERFACE
REAL FUNCTION p()
END
END INTERFACE
END
END INTERFACE
INTERFACE
REAL FUNCTION x()
END
END INTERFACE
INTERFACE
SUBROUTINE y
END
END INTERFACE
call g (x)
call g (y)
END
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
! standard explicitly does not require recursion into the formal ! standard explicitly does not require recursion into the formal
! arguments of procedures that themselves are interface arguments. ! arguments of procedures that themselves are interface arguments.
! !
module x module xx
INTERFACE BAD9 INTERFACE BAD9
SUBROUTINE S9A(X) SUBROUTINE S9A(X)
REAL :: X REAL :: X
...@@ -27,6 +27,6 @@ module x ...@@ -27,6 +27,6 @@ module x
END INTERFACE END INTERFACE
END SUBROUTINE S9C ! { dg-error "Ambiguous interfaces" } END SUBROUTINE S9C ! { dg-error "Ambiguous interfaces" }
END INTERFACE BAD9 END INTERFACE BAD9
end module x end module xx
! { dg-final { cleanup-modules "x" } } ! { dg-final { cleanup-modules "xx" } }
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