summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>2006-12-09 20:52:27 +0000
committerpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>2006-12-09 20:52:27 +0000
commit47b07579d3eda6e5afe4d7163b982f46a7eda082 (patch)
treee1bb0983bc4f7aef81f313ba20585da56a4b546a
parent48a3e2a88420ebebe83cb52ecfbb80eb200b7f1d (diff)
downloadgcc-47b07579d3eda6e5afe4d7163b982f46a7eda082.tar.gz
2006-11-25 Paul Thomas <pault@gcc.gnu.org>
PR fortran/29464 * module.c (load_generic_interfaces): Add symbols for all the local names of an interface. Share the interface amongst the symbols. * gfortran.h : Add generic_copy to symbol_attribute. * symbol.c (free_symbol): Only free interface if generic_copy is not set. 2006-11-25 Paul Thomas <pault@gcc.gnu.org> PR fortran/29464 * gfortran.dg/module_interface_2.f90: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119696 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/fortran/ChangeLog10
-rw-r--r--gcc/fortran/gfortran.h2
-rw-r--r--gcc/fortran/module.c44
-rw-r--r--gcc/fortran/symbol.c3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/module_interface_2.f9031
6 files changed, 79 insertions, 16 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 1a6b28afcde..f3602064f96 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,5 +1,15 @@
2006-12-09 Paul Thomas <pault@gcc.gnu.org>
+ PR fortran/29464
+ * module.c (load_generic_interfaces): Add symbols for all the
+ local names of an interface. Share the interface amongst the
+ symbols.
+ * gfortran.h : Add generic_copy to symbol_attribute.
+ * symbol.c (free_symbol): Only free interface if generic_copy
+ is not set.
+
+2006-12-09 Paul Thomas <pault@gcc.gnu.org>
+
PR fortran/29941
* resolve.c (resolve_function): Add LEN to the functions not
checked for assumed size actual args.
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 3a3b680f88f..5e4b322aebf 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -486,7 +486,7 @@ typedef struct
use_assoc:1; /* Symbol has been use-associated. */
unsigned in_namelist:1, in_common:1, in_equivalence:1;
- unsigned function:1, subroutine:1, generic:1;
+ unsigned function:1, subroutine:1, generic:1, generic_copy:1;
unsigned implicit_type:1; /* Type defined via implicit rules. */
unsigned untyped:1; /* No implicit type could be found. */
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index 6956fc980c5..7c9c2b1ab3c 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -3024,6 +3024,8 @@ load_generic_interfaces (void)
const char *p;
char name[GFC_MAX_SYMBOL_LEN + 1], module[GFC_MAX_SYMBOL_LEN + 1];
gfc_symbol *sym;
+ gfc_interface *generic = NULL;
+ int n, i;
mio_lparen ();
@@ -3034,25 +3036,39 @@ load_generic_interfaces (void)
mio_internal_string (name);
mio_internal_string (module);
- /* Decide if we need to load this one or not. */
- p = find_use_name (name);
+ n = number_use_names (name);
+ n = n ? n : 1;
- if (p == NULL || gfc_find_symbol (p, NULL, 0, &sym))
+ for (i = 1; i <= n; i++)
{
- while (parse_atom () != ATOM_RPAREN);
- continue;
- }
+ /* Decide if we need to load this one or not. */
+ p = find_use_name_n (name, &i);
- if (sym == NULL)
- {
- gfc_get_symbol (p, NULL, &sym);
+ if (p == NULL || gfc_find_symbol (p, NULL, 0, &sym))
+ {
+ while (parse_atom () != ATOM_RPAREN);
+ continue;
+ }
- sym->attr.flavor = FL_PROCEDURE;
- sym->attr.generic = 1;
- sym->attr.use_assoc = 1;
- }
+ if (sym == NULL)
+ {
+ gfc_get_symbol (p, NULL, &sym);
- mio_interface_rest (&sym->generic);
+ sym->attr.flavor = FL_PROCEDURE;
+ sym->attr.generic = 1;
+ sym->attr.use_assoc = 1;
+ }
+ if (i == 1)
+ {
+ mio_interface_rest (&sym->generic);
+ generic = sym->generic;
+ }
+ else
+ {
+ sym->generic = generic;
+ sym->attr.generic_copy = 1;
+ }
+ }
}
mio_rparen ();
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 228567bd5e8..7cb5e762de5 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -1971,7 +1971,8 @@ gfc_free_symbol (gfc_symbol * sym)
gfc_free_namespace (sym->formal_ns);
- gfc_free_interface (sym->generic);
+ if (!sym->attr.generic_copy)
+ gfc_free_interface (sym->generic);
gfc_free_formal_arglist (sym->formal);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 761d53bb660..5204470816a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2006-12-09 Paul Thomas <pault@gcc.gnu.org>
+ PR fortran/29464
+ * gfortran.dg/module_interface_2.f90: New test.
+
+2006-12-09 Paul Thomas <pault@gcc.gnu.org>
+
PR fortran/29941
* gfortran.dg/assumed_len.f90: New test.
diff --git a/gcc/testsuite/gfortran.dg/module_interface_2.f90 b/gcc/testsuite/gfortran.dg/module_interface_2.f90
new file mode 100644
index 00000000000..1f9fde81edb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/module_interface_2.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+! Tests the fix for PR29464, in which the second USE of the generic
+! interface caused an error.
+!
+! Contributed by Vivek Rao <vivekrao4@yahoo.com>
+!
+module foo_mod
+ implicit none
+ interface twice
+ module procedure twice_real
+ end interface twice
+contains
+ real function twice_real(x)
+ real :: x
+ twice_real = 2*x
+ end function twice_real
+end module foo_mod
+
+ subroutine foobar ()
+ use foo_mod, only: twice, twice
+ print *, twice (99.0)
+ end subroutine foobar
+
+ program xfoo
+ use foo_mod, only: two => twice, dbl => twice
+ implicit none
+ call foobar ()
+ print *, two (2.3)
+ print *, dbl (2.3)
+end program xfoo
+! { dg-final { cleanup-modules "foo_mod" } }