Bug 60777 - [F03] RECURSIVE function rejected in specification expression
Summary: [F03] RECURSIVE function rejected in specification expression
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: 7.0
Assignee: janus
URL:
Keywords: rejects-valid
Depends on:
Blocks: F2003
  Show dependency treegraph
 
Reported: 2014-04-07 14:22 UTC by Vladimir Fuka
Modified: 2016-11-09 17:37 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-04-09 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vladimir Fuka 2014-04-07 14:22:18 UTC
John Harper reports on comp.lang.fortran:

! A recursive function in a specification expression
  module recur 
    implicit none
  contains
 
    pure recursive function f(n) result(answer)
      integer,intent(in) ::   n
      integer            ::             answer
      if (n<2) then
         answer = 1
      else
         answer = f(n-1)*n
      end if
    end function f ! factorial of max(n,0)
 
    pure function usef(    n)
      integer,intent(in):: n
      character(f(n))   :: usef
      usef = repeat('*',f(n))
    end function usef
  end module recur
 
  program testspecexpr
    use recur
    implicit none
    integer :: n
    do n = 1,3
       print *,usef(n)
    end do
  end program testspecexpr



Which gives gfortran-4.9 resspec.f90 
resspec.f90:18.16:

      character(f(n))   :: usef
                1
Error: Specification function 'f' at (1) cannot be RECURSIVE



but Fortran 2003 and 2008 just require:

7.1.11.6 (F2008): Evaluation of a specification expression shall not directly or indirectly cause a procedure defined by the subprogram in which it appears to be invoked.
Comment 1 kargl 2014-04-07 14:29:51 UTC
Index: expr.c
===================================================================
--- expr.c      (revision 208947)
+++ expr.c      (working copy)
@@ -2733,12 +2733,10 @@ external_spec_function (gfc_expr *e)
       return false;
     }
 
-  if (f->attr.recursive)
-    {
-      gfc_error ("Specification function '%s' at %L cannot be RECURSIVE",
-                f->name, &e->where);
+  if (f->attr.recursive
+      && !gfc_notify_std (GFC_STD_F2003, "Specification function '%s' "
+                         "at %L cannot be RECURSIVE",  f->name, &e->where));
       return false;
-    }
 
   return restricted_args (e->value.function.actual);
 }
Comment 2 Dominique d'Humieres 2014-04-09 08:32:36 UTC
Confirmed.
Comment 3 janus 2016-11-08 14:37:07 UTC
Steve, do you wanna go ahead with the patch in comment 1, or is there something wrong with it?
Comment 4 kargl 2016-11-08 15:05:01 UTC
(In reply to janus from comment #3)
> Steve, do you wanna go ahead with the patch in comment 1, or is there
> something wrong with it?

To be honest, I don't remember this bug nor why I did not
finish the patch (i.e., convert example to testcase).  If
you feel that the patch in comment #3 is correct, you are
more than welcomed to commit it.
Comment 5 janus 2016-11-09 11:02:50 UTC
(In reply to kargl from comment #4)
> If
> you feel that the patch in comment #3 is correct, you are
> more than welcomed to commit it.

It does look good at first glance. I'll test it and commit if successful.
Comment 6 janus 2016-11-09 14:56:39 UTC
I think the patch in comment 1 actually does not work as expected (due to a spurious semicolon).

However, this variant seems to work well and regtests cleanly:


Index: gcc/fortran/expr.c
===================================================================
--- gcc/fortran/expr.c	(revision 241997)
+++ gcc/fortran/expr.c	(working copy)
@@ -2794,12 +2794,12 @@
       return false;
     }
 
-  if (f->attr.recursive)
-    {
-      gfc_error ("Specification function %qs at %L cannot be RECURSIVE",
-		 f->name, &e->where);
+  /* F08:7.1.11.6. */
+  if (f->attr.recursive
+      && !gfc_notify_std (GFC_STD_F2003,
+			  "Specification function '%s' "
+			  "at %L cannot be RECURSIVE",  f->name, &e->where))
       return false;
-    }
 
 function_allowed:
   return restricted_args (e->value.function.actual);


I will commit this soon.
Comment 7 janus 2016-11-09 17:22:33 UTC
Author: janus
Date: Wed Nov  9 17:22:02 2016
New Revision: 242009

URL: https://gcc.gnu.org/viewcvs?rev=242009&root=gcc&view=rev
Log:
2016-11-09  Steve Kargl <kargl@gcc.gnu.org>
	    Janus Weil  <janus@gcc.gnu.org>

	PR fortran/60777
	* expr.c (external_spec_function): Allow recursive specification
	functions in F03.

2016-11-09  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/60777
	* gfortran.dg/spec_expr_7.f90: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/spec_expr_7.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/expr.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 janus 2016-11-09 17:37:12 UTC
Fixed with r242009. Closing.