This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch, Fortran] PR 33818 - Fix bogus error dummy variable is used before the entry statement
- From: Tobias Burnus <burnus at net-b dot de>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>, "'fortran at gcc dot gnu dot org'" <fortran at gcc dot gnu dot org>, Alan Greynolds <awgreynolds at earthlink dot net>
- Date: Sat, 20 Oct 2007 00:36:42 +0200
- Subject: [Patch, Fortran] PR 33818 - Fix bogus error dummy variable is used before the entry statement
:ADDPATCH fortran:
The error message
Error: Variable 'str' is used at (1) before the ENTRY statement in
which it is a parameter
is printed as diagnostic, if a dummy variable is used which does not
belong to the current entry function, e.g.
subroutine foo(x)
integer :: y
character(len(y)) :: x ! wrongly accesses "y"
entry(y)
Well, in this bug the problem is that the expression
write(lu,'(a)') 'UNIT '//UpperCase(UNAME)
contains the specification expression for
character(len(str)) :: UpperCase
of the interface function "Uppercase".
If now in resolve_variable, the symbol is checked, current_ns is the
namespace of the expression (namespace "subroutine ExportZMX") and
sym->name is "str" (namespace "function UpperCase").
Well, the check now does
if (sym->attr.dummy)
which is true and then it checks whether sym->name matches any of the
arguments of the current namespace (which is not the case) and therefore
an error is printed.
It is not obvious why it fails all of a sudden, but as Jerry has
checked, the triggering patch is
http://gcc.gnu.org/viewcvs?view=rev&revision=127939 (or at least 127938
works and it fails with a version shortly afterwards). The patch 127939
looks innocent; but it somehow causes resolve_variable to be called.
* * *
Immediately after I posted my patch (see attachment) to bugzilla and
completely independent, Paul send me an email with a different version
of the patch.
Both patches have in the end the same effect and both regression test on
x86-64/Linux.
OK for the trunk? And if yes, which version is prefered?
Tobias
Paul Thomas wrote:
> The patch below fixes the PR and
> regtests but I think that it breaks the check on forward referencing.
> Certainly this is the epicentre of the problem:-) [...]
>
Side note: I think it still works - at least entry_dummy_ref_*.f90
regression test and they have such test cases.
> What I cannot understand is how this came to be a regression. I can
> see nothing in the ChangeLogs that looks like the culprit.
> [...]
>
> Index: /svn/trunk/gcc/fortran/resolve.c
> ===================================================================
> *** /svn/trunk/gcc/fortran/resolve.c (revision 129417)
> --- /svn/trunk/gcc/fortran/resolve.c (working copy)
> *************** resolve_variable (gfc_expr *e)
> *** 3923,3929 ****
>
> /* Deal with forward references to entries during resolve_code, to
> satisfy, at least partially, 12.5.2.5. */
> ! if (gfc_current_ns->entries
> && current_entry_id == sym->entry_id
> && cs_base
> && cs_base->current
> --- 3923,3929 ----
>
> /* Deal with forward references to entries during resolve_code, to
> satisfy, at least partially, 12.5.2.5. */
> ! if (sym->ns->entries
> && current_entry_id == sym->entry_id
> && cs_base
> && cs_base->current
> *************** resolve_variable (gfc_expr *e)
> *** 3937,3943 ****
> /* If the symbol is a dummy... */
> if (sym->attr.dummy)
> {
> ! entry = gfc_current_ns->entries;
> seen = false;
>
> /* ...test if the symbol is a parameter of previous entries. */
> --- 3937,3943 ----
> /* If the symbol is a dummy... */
> if (sym->attr.dummy)
> {
> ! entry = sym->ns->entries;
> seen = false;
>
> /* ...test if the symbol is a parameter of previous entries. */
2007-10-20 Tobias Burnus <burnus@net-b.de>
PR fortran/33818
* resolve.c (resolve_variable): Check that symbol is in the same
namespace as the entry function.
2007-10-20 Tobias Burnus <burnus@net-b.de>
PR fortran/33818
* gfortran.dg/entry_dummy_ref_3.f90: New.
Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c (revision 129495)
+++ gcc/fortran/resolve.c (working copy)
@@ -3935,7 +3935,7 @@ resolve_variable (gfc_expr *e)
bool seen;
/* If the symbol is a dummy... */
- if (sym->attr.dummy)
+ if (sym->attr.dummy && sym->ns == gfc_current_ns)
{
entry = gfc_current_ns->entries;
seen = false;
@@ -3952,8 +3952,8 @@ resolve_variable (gfc_expr *e)
if (!seen)
{
if (specification_expr)
- gfc_error ("Variable '%s',used in a specification expression, "
- "is referenced at %L before the ENTRY statement "
+ gfc_error ("Variable '%s', used in a specification expression"
+ ", is referenced at %L before the ENTRY statement "
"in which it is a parameter",
sym->name, &cs_base->current->loc);
else
Index: gcc/testsuite/gfortran.dg/entry_dummy_ref_3.f90
===================================================================
--- gcc/testsuite/gfortran.dg/entry_dummy_ref_3.f90 (revision 0)
+++ gcc/testsuite/gfortran.dg/entry_dummy_ref_3.f90 (revision 0)
@@ -0,0 +1,25 @@
+! { dg-do compile }
+!
+! PR fortran/33818
+!
+
+subroutine ExportZMX(lu)
+ implicit none
+ integer :: lu
+ interface
+ function LowerCase(str)
+ character(*),intent(in) :: str
+ character(len(str)) :: LowerCase
+ end function LowerCase
+ end interface
+ character(*),parameter :: UNAME(1:1)=(/'XXX'/)
+ write(lu,'(a)') 'UNIT '//UpperCase(UNAME(1))
+ write(lu,'(a)') 'Unit '//LowerCase(UNAME(1))
+entry ExportSEQ(lu)
+contains
+ function UpperCase(str) result(res)
+ character(*),intent(in) :: str
+ character(len(str)) res
+ res=str
+ end function
+end