Allocatable components to the right of a nonzero-rank part reference

erik.edelmann@iki.fi erik.edelmann@iki.fi
Thu Nov 16 21:35:00 GMT 2006


According to the standard, "A part-name to the right of a part-ref with
nonzero rank shall not have the ALLOCATABLE or POINTER attribute." (F2003 draft
standard, page 105, lines 12-13).

Currently we accept it for ALLOCATABLEs for some cases (e.g. as procedure
arguments, and in WHEREs), but get ICEs for other cases (e.g. plain
array assignments).

The question now is what we should do about this. We could

        (a) Allways reject (attached patch does that).

        (b) Accept it as an extension.  Those cases that don't work can be
        implemented eventually (I can open a PR).  This would be a nice
        extension, but it has the downside that it could get quite
        complicated.  I haven't thought a lot about it, but I guess that
        e.g.

                p => x(:)%y(1)

        where y is an allocatable component, is somewhere between
        difficult and impossible to implement.

        (c) Like (b), but reject the most difficult cases.

Perhaps we could do (a) for 4.2, and (c) for 4.3?  Opinions?



        Erik
-------------- next part --------------
Index: gcc/testsuite/gfortran.dg/alloc_comp_assign_2.f90
===================================================================
--- gcc/testsuite/gfortran.dg/alloc_comp_assign_2.f90	(revision 118859)
+++ gcc/testsuite/gfortran.dg/alloc_comp_assign_2.f90	(working copy)
@@ -38,12 +38,6 @@
   if (any( (/(((y(k)%at(i)%i(j), j = 1,4), i = 1,2), k = 1,2)/) .ne. &
          (/0,0,2,1,11,12,6,5,11,12,3,2,9,8,7,6/))) call abort () 
 
-  where (y((2))%at(:)%i(2) > 8)
-    y(2)%at(:)%i(2) = 77
-  end where
-  if (any ((/(((y(k)%at(i)%i(j), j = 1,4), i = 1,2), k = 1,2)/) .ne. &
-         (/0,0,2,1,11,12,6,5,11,77,3,2,9,8,7,6/))) call abort ()
-
 ! Check that temporaries and full array  alloctable component assignments
 ! are correctly handled in FORALL.
 
Index: gcc/testsuite/gfortran.dg/alloc_comp_constraint_5.f90
===================================================================
--- gcc/testsuite/gfortran.dg/alloc_comp_constraint_5.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/alloc_comp_constraint_5.f90	(revision 0)
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! Check that ALLOCATABLE components aren't allowed to the right of a non-zero
+! rank pasrt reference.
+program test
+
+    implicit none
+    type :: foo
+        real, allocatable :: bar(:)
+    end type foo
+    type(foo) :: x(3)
+
+    allocate(x%bar(5))  ! { dg-error "must not have the ALLOCATABLE attribute" }
+    x%bar(1) = 1.0      ! { dg-error "must not have the ALLOCATABLE attribute" }
+
+end program test
Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 118859)
+++ gcc/fortran/resolve.c	(working copy)
@@ -2797,14 +2797,24 @@ resolve_ref (gfc_expr * expr)
 	  break;
 
 	case REF_COMPONENT:
-	  if ((current_part_dimension || seen_part_dimension)
-	      && ref->u.c.component->pointer)
+	  if (current_part_dimension || seen_part_dimension)
 	    {
-	      gfc_error
-		("Component to the right of a part reference with nonzero "
-		 "rank must not have the POINTER attribute at %L",
-		 &expr->where);
-	      return FAILURE;
+	      if (ref->u.c.component->pointer)
+	        {
+		  gfc_error
+		    ("Component to the right of a part reference with nonzero "
+		     "rank must not have the POINTER attribute at %L",
+		     &expr->where);
+		  return FAILURE;
+		}
+	      else if (ref->u.c.component->allocatable)
+	        {
+		  gfc_error
+		    ("Component to the right of a part reference with nonzero "
+		     "rank must not have the ALLOCATABLE attribute at %L",
+		     &expr->where);
+		  return FAILURE;
+		}
 	    }
 
 	  n_components++;


More information about the Fortran mailing list