From: burnus Date: Thu, 15 Nov 2007 15:12:03 +0000 (+0000) Subject: 2007-11-15 Tobias Burnus X-Git-Tag: upstream/4.9.2~45071 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=741136441d1b8e0302021f66bf6c33957c7404b2;p=platform%2Fupstream%2Flinaro-gcc.git 2007-11-15 Tobias Burnus PR fortran/33917 * decl.c (match_procedure_decl): Pre-resolve interface. * resolve.c (resolve_symbol): Reject interfaces later declared in procedure statements. 2007-11-15 Tobias Burnus PR fortran/33917 * gfortran.dg/proc_decl_11.f90: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130202 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index a38d4ad..5411776 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,10 @@ +2007-11-15 Tobias Burnus + + PR fortran/33917 + * decl.c (match_procedure_decl): Pre-resolve interface. + * resolve.c (resolve_symbol): Reject interfaces later + declared in procedure statements. + 2007-11-13 Jerry DeLisle PR fortran/33162 diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 29b02ea..be197bc 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -3946,6 +3946,12 @@ match_procedure_decl (void) /* Various interface checks. */ if (proc_if) { + /* Resolve interface if possible. That way, attr.procedure is only set + if it is declared by a later procedure-declaration-stmt, which is + invalid per C1212. */ + while (proc_if->interface) + proc_if = proc_if->interface; + if (proc_if->generic) { gfc_error ("Interface '%s' at %C may not be generic", proc_if->name); diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 3f3ef03..586d601 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -7615,8 +7615,10 @@ resolve_symbol (gfc_symbol *sym) if (sym->attr.procedure && sym->interface && sym->attr.if_source != IFSRC_DECL) { - while (sym->interface->interface) - sym->interface = sym->interface->interface; + if (sym->interface->attr.procedure) + gfc_error ("Interface '%s', used by procedure '%s' at %L, is declared " + "in a later PROCEDURE statement", sym->interface->name, + sym->name,&sym->declared_at); /* Get the attributes from the interface (now resolved). */ if (sym->interface->attr.if_source || sym->interface->attr.intrinsic) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d937f4f..b3e26c0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-11-15 Tobias Burnus + + PR fortran/33917 + * gfortran.dg/proc_decl_11.f90: New. + 2007-11-15 Ben Elliston * gcc.target/spu/compare-dp.c: New test. diff --git a/gcc/testsuite/gfortran.dg/proc_decl_11.f90 b/gcc/testsuite/gfortran.dg/proc_decl_11.f90 new file mode 100644 index 0000000..74c0680 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/proc_decl_11.f90 @@ -0,0 +1,34 @@ +! { dg-do compile } +! PR fortran/33917 +! +! Depending, in which order the symbol tree +! was walked in resolve, gfortran resolved +! p6 before p4; thus there was no explicit +! interface available for p4 and an error +! was printed. (This is a variant of proc_decl_2.f90) +! +! Additionally, the following contrain was not honoured: +! "C1212 (R1215) [...] If name is declared by a procedure-declaration-stmt +! it shall be previously declared." ("name" = interface-name) +! +program s + implicit none + procedure() :: q2 + procedure() :: q3 + procedure() :: q5 + procedure(sub) :: p4 + procedure(p4) :: p6 +contains + subroutine sub + end subroutine +end program s + +subroutine test + implicit none + abstract interface + subroutine sub() + end subroutine sub + end interface + procedure(p4) :: p6 ! { dg-error "declared in a later PROCEDURE statement" } + procedure(sub) :: p4 +end subroutine test