Bug 54756 - [OOP] [F08] Should reject CLASS, intent(out) in PURE procedures
Summary: [OOP] [F08] Should reject CLASS, intent(out) in PURE procedures
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: janus
Keywords: accepts-invalid
Depends on:
Reported: 2012-09-29 18:19 UTC by Tobias Burnus
Modified: 2014-12-27 22:43 UTC (History)
2 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed: 2014-12-21 00:00:00


Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2012-09-29 18:19:06 UTC
Fortran 2008 no longer allows CLASS(),INTENT(OUT) in PURE procedures, gfortran accepts those.

(Note: I think one should also reject them for Fortran 2003 as it seems to make life easier easier for the FINAL implementation.)

See "TECHNICAL CORRIGENDUM 1" to Fortran 2008, ftp://ftp.nag.co.uk/sc22wg5/N1901-N1950/N1902.pdf in "Subclause 1.6.2"
See also ftp://ftp.nag.co.uk/sc22wg5/N1851-N1900/N1875.txt for f08/0011 and f08/0033.

"Fortran 2003 permitted an INTENT(OUT) argument of a pure subroutine to be polymorphic; that is not permitted by this part of ISO/IEC 153."

Side note: That doesn't seem to affect impure (elemental).

type t
end type t
pure subroutine foo(x)
  class(t), intent(out) :: x
end subroutine
Comment 1 Tobias Burnus 2012-09-29 18:30:38 UTC
The constraint belonging to that note (from the same corrigendum):

"C1278a  An INTENT(OUT) dummy argument of a pure procedure shall not be

I think the rational is that a FINAL subroutine might be IMPURE and one could thus invoke an IMPURE procedure through that back door - and it is not detectable at compile time.

  * * *

Note that there is the related constraint:

C1284a   A statement that might result in the deallocation of a polymorphic entity is not permitted in a pure procedure.

NOTE 12.48x
Apart from the DEALLOCATE statement, this includes intrinsic assignment if the variable has a polymorphic allocatable component at any level of component selection that does not involve a pointer component but which might involve one or more allocatable components.
Comment 2 Tobias Burnus 2012-09-29 18:33:32 UTC
As follow up - and side note: The following constraint ensures that there is a compile-time error if one tries this with a nonpolymorphic entries. I am not sure whether we currently handle it. (From Fortran 2008:)

"C1284  Any procedure referenced in a pure subprogram, including one referenced via a defined operation, defined assignment, defined input/output, or finalization, shall be pure."
Comment 3 janus 2012-11-06 10:10:35 UTC
Related test case:

module moda
 implicit none
 type t
  real, pointer :: p => null()
 end type t

 pure subroutine s1(a,b)
  type(t), intent(in) :: b
  class(t), allocatable, intent(out) :: a
 end subroutine

 pure subroutine s2(a,b)
  type(t), intent(in) :: b
  class(t), allocatable, intent(out) :: a
   a%p => b%p
 end subroutine

end module  

(slightly modified version of the one posted at https://groups.google.com/forum/?fromgroups=#!topic/comp.lang.fortran/Vj6a0tM5cvs)

Currently only the second case is rejected due to "Bad target in pointer assignment in PURE procedure". Possibly the same should apply to the first one?

Anyway, both should be rejected due to the CLASS, INTENT(OUT) argument.
Comment 4 janus 2012-11-06 17:58:36 UTC
Draft patch:

Index: gcc/fortran/resolve.c
--- gcc/fortran/resolve.c	(revision 193224)
+++ gcc/fortran/resolve.c	(working copy)
@@ -419,6 +419,16 @@ resolve_formal_arglist (gfc_symbol *proc)
+	  /* F08:C1278a.  */
+	  if (sym->ts.type == BT_CLASS && sym->attr.intent == INTENT_OUT
+	      && (gfc_option.allow_std & GFC_STD_F2008) != 0)
+	    {
+	      gfc_error ("INTENT(OUT) argument '%s' of pure procedure '%s' "
+			 "at %L may not be polymorphic in Fortran 2008",
+			 sym->name, proc->name, &sym->declared_at);
+	      continue;
+	    }
       if (proc->attr.implicit_pure)

Unfortunately, we cannot use 'gfc_notify_std' here (or we would need to add something like GFC_STD_F2008_DEL, although this is not officially a 'deleted feature', I guess).

So, we could just go with the above, or alternatively reject it regardless of the chosen standard. This 'feature' probably counts as an 'oversight' which was missed in F03 and added to F08 only in a corrigendum.
Comment 5 janus 2012-11-06 21:19:54 UTC
(In reply to comment #4)
> Draft patch:

In fact this causes a number of testsuite failures:

FAIL: gfortran.dg/class_array_3.f03  -O0  (test for excess errors)
FAIL: gfortran.dg/class_array_7.f03  -O0  (test for excess errors)
FAIL: gfortran.dg/class_dummy_4.f03  -O  (test for excess errors)
FAIL: gfortran.dg/typebound_operator_4.f03  -O  (test for excess errors)
FAIL: gfortran.dg/typebound_proc_16.f03  -O  (test for excess errors)

I think that all of the errors are correct (meaning the test cases are invalid).
Comment 6 Dominique d'Humieres 2014-12-21 12:18:56 UTC
Patch at https://gcc.gnu.org/ml/fortran/2014-12/msg00098.html.
Comment 7 janus 2014-12-22 15:56:10 UTC
Closely related: PR 59103.
Comment 8 janus 2014-12-27 22:40:54 UTC
Author: janus
Date: Sat Dec 27 22:40:21 2014
New Revision: 219085

URL: https://gcc.gnu.org/viewcvs?rev=219085&root=gcc&view=rev
2014-12-27  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/54756
	* resolve.c (resolve_formal_arglist): Reject polymorphic INTENT(OUT)
	arguments of pure procedures.

2014-12-27  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/54756
	* gfortran.dg/class_array_3.f03: Fixed invalid test case.
	* gfortran.dg/class_array_7.f03: Ditto.
	* gfortran.dg/class_dummy_4.f03: Ditto.
	* gfortran.dg/defined_assignment_3.f90: Ditto.
	* gfortran.dg/defined_assignment_5.f90: Ditto.
	* gfortran.dg/elemental_subroutine_10.f90: Ditto.
	* gfortran.dg/typebound_operator_4.f03: Ditto.
	* gfortran.dg/typebound_proc_16.f03: Ditto.
	* gfortran.dg/unlimited_polymorphic_19.f90: Ditto.
	* gfortran.dg/class_dummy_5.f90: New test.

Comment 9 janus 2014-12-27 22:43:48 UTC
Fixed with r219085. Closing.