Patchwork [Fortran] PR46484: Function-expressions are not variables

login
register
mail settings
Submitter Tobias Burnus
Date Nov. 15, 2010, 4:41 p.m.
Message ID <4CE162A5.2060408@net-b.de>
Download mbox | patch
Permalink /patch/71242/
State New
Headers show

Comments

Tobias Burnus - Nov. 15, 2010, 4:41 p.m.
The following patch is kind of obvious - at least for Fortran 
90/95/2003: A function call is not a variable!*

In terms of the check.c, e.g., the following example will cease to work, 
however, as the code is dubious, that should be no problem.

print *, loc(sub()) ! Fails with the patch
contains
   integer function sub()
     sub = 4
   end function
end

Note: Using "loc(sub)" still works [and returns the address of the function]

Build and regtested on x86-64-linux.
OK for the trunk?

Tobias

PS: In GCC 4.5/4.6 the new test case just compiles; in older GCCs one 
gets a nice error message with an unhelpful location as gfc_get_attr 
gives an ICE. The line in check.c itself, I could trace back to GCC 4.0.0.

* For Fortran 2008: A pointer-returning function counts as "variable" 
(R602, C602, PR 40054), but that's not yet implemented.

Patch

2010-11-15  Tobias Burnus  <burnus@net.b.de>

	PR fortran/46484
	* check.c (variable_check): Don't treat functions as variables.

2010-11-15  Tobias Burnus  <burnus@net.b.de>

	PR fortran/46484
	* gfortran.dg/allocatable_scalar_11.f90: New.
	gfortran.dg/allocatable_scalar_5.f90: Make test case standard conform.

diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
index 51ea877..cc36fea 100644
--- a/gcc/fortran/check.c
+++ b/gcc/fortran/check.c
@@ -491,10 +491,8 @@  variable_check (gfc_expr *e, int n)
       return FAILURE;
     }
 
-  if ((e->expr_type == EXPR_VARIABLE
+  if (e->expr_type == EXPR_VARIABLE
        && e->symtree->n.sym->attr.flavor != FL_PARAMETER)
-      || (e->expr_type == EXPR_FUNCTION
-	  && e->symtree->n.sym->result == e->symtree->n.sym))
     return SUCCESS;
 
   gfc_error ("'%s' argument of '%s' intrinsic at %L must be a variable",
diff --git a/gcc/testsuite/gfortran.dg/allocatable_scalar_11.f90 b/gcc/testsuite/gfortran.dg/allocatable_scalar_11.f90
new file mode 100644
index 0000000..e1b1a87
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/allocatable_scalar_11.f90
@@ -0,0 +1,13 @@ 
+! { dg-compile }
+!
+! PR fortran/46484
+!
+
+implicit none
+logical :: ll
+ll = allocated (f()) ! { dg-error "must be a variable" }
+contains
+  function f()
+    integer, allocatable :: f
+  end function f
+end
diff --git a/gcc/testsuite/gfortran.dg/allocatable_scalar_5.f90 b/gcc/testsuite/gfortran.dg/allocatable_scalar_5.f90
index cee95a1..efa40e9 100644
--- a/gcc/testsuite/gfortran.dg/allocatable_scalar_5.f90
+++ b/gcc/testsuite/gfortran.dg/allocatable_scalar_5.f90
@@ -1,7 +1,7 @@ 
 ! { dg-do run }
 ! { dg-options "-Wall -pedantic" }
 !
-! PR fortran/41872
+! PR fortran/41872; updated due to PR fortran/46484
 !
 !  More tests for allocatable scalars
 !
@@ -11,8 +11,6 @@  program test
   integer :: b
 
   if (allocated (a)) call abort ()
-  if (allocated (func (.false.))) call abort ()
-  if (.not.allocated (func (.true.))) call abort ()
   b = 7
   b = func(.true.)
   if (b /= 5332) call abort () 
@@ -28,7 +26,6 @@  program test
   call intout2 (a)
   if (allocated (a)) call abort ()
 
-  if (allocated (func2 ())) call abort ()
 contains
 
   function func (alloc)
@@ -41,10 +38,6 @@  contains
     end if
   end function func
 
-  function func2 ()
-    integer, allocatable ::  func2
-  end function func2
-
   subroutine intout (dum, alloc)
     implicit none
     integer, allocatable,intent(out) :: dum