diff options
author | pault <pault@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-12-09 20:52:27 +0000 |
---|---|---|
committer | pault <pault@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-12-09 20:52:27 +0000 |
commit | 47b07579d3eda6e5afe4d7163b982f46a7eda082 (patch) | |
tree | e1bb0983bc4f7aef81f313ba20585da56a4b546a | |
parent | 48a3e2a88420ebebe83cb52ecfbb80eb200b7f1d (diff) | |
download | gcc-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/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 2 | ||||
-rw-r--r-- | gcc/fortran/module.c | 44 | ||||
-rw-r--r-- | gcc/fortran/symbol.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/module_interface_2.f90 | 31 |
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" } } |