This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Double initialization of variables (PR 50410, RFC patch)


Hello all,

which double intializations should gfortran allow?

With the attached patch, one only allows double DATA initialization, however, that causes regressions as it disallows to combine assignment initialization followed by DATA initialization.

In other words: It fails for the second dg-error in gfortran.dg/data_initialized.f90 as with the patch the case is always rejected.

On the other hand, with the current version, one gets an ICE for:

subroutine one()
type t1
integer g
end type t1
type(t1) :: u=t1(1)
data u%g /2/ ! { dg-error "is already initialized and may thus not be in the DATA statement" }
print *, u%g
end


Other compilers seem to support this - some print 1 and others print 2.

What do you think? Is the current patch OK, which rejects this? Or should one one try harder to also allow this kind of double initialization.


Tobias
NOTE: Fails for gfortran.dg/data_initialized.f90 as
extension "re-initialization" is no longer allowed for
the second case.

Also fails for:

gfortran.dg/data_initialized_2.f90
gfortran.dg/data_invalid.f90
gfortran.dg/data_pointer_1.f90

But I have not analysed them.

2011-10-18  Tobias Burnus  <burnus@net-b.de>

	PR fortran/50410
	* data.c (gfc_assign_data_value): Check that pointers
	are only NULL() initialized.
	* decl.c (var_element): Add initialization constraint checks.

2011-10-18  Tobias Burnus  <burnus@net-b.de>

	PR fortran/50410
	* gfortran.dg/data_initialized_3.f90: New.
	* gfortran.dg/data_constraints_1.f90: Update dg-error.

diff --git a/gcc/fortran/data.c b/gcc/fortran/data.c
index 67da371..3d52e3a 100644
--- a/gcc/fortran/data.c
+++ b/gcc/fortran/data.c
@@ -212,6 +212,13 @@ gfc_assign_data_value (gfc_expr *lvalue, gfc_expr *rvalue, mpz_t index,
   last_con = NULL;
   mpz_init_set_si (offset, 0);
 
+  if (gfc_expr_attr (lvalue).pointer && rvalue->expr_type != EXPR_NULL)
+    {
+      gfc_error ("NULL() initialization expected in DATA statement for pointer "
+		 " '%s' at %L", symbol->name, &rvalue->where);
+      return FAILURE;
+    }
+
   /* Find/create the parent expressions for subobject references.  */
   for (ref = lvalue->ref; ref; ref = ref->next)
     {
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 2dd38b9..2d3a519 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -237,6 +237,7 @@ var_element (gfc_data_variable *new_var)
 {
   match m;
   gfc_symbol *sym;
+  gfc_ref *ref;
 
   memset (new_var, 0, sizeof (gfc_data_variable));
 
@@ -269,6 +270,37 @@ var_element (gfc_data_variable *new_var)
 			 sym->name) == FAILURE)
     return MATCH_ERROR;
 
+  if (!sym->attr.data && sym->value)
+    {
+      gfc_error ("Variable '%s' is already initialized and may thus not be "
+		 "in the DATA statement at %C", sym->name);
+      return MATCH_ERROR;
+    }
+
+  if (sym->ts.type == BT_DERIVED && gfc_has_default_initializer (sym->ts.u.derived))
+    {
+      gfc_error ("Variable '%s' has a default initializer and may thus not be "
+		 "in the DATA statement at %C", sym->name);
+      return MATCH_ERROR;
+    }
+
+  for (ref = new_var->expr->ref; ref; ref = ref->next)
+    if (ref->type == REF_COMPONENT
+	&& (ref->u.c.sym->attr.pointer
+	    || ref->u.c.sym->attr.allocatable))
+      break;
+
+  /* Reject DATA initialization of an allocatable or pointer, but allow a
+     pointer last for null() initialization.  */
+  if (sym->attr.allocatable || (sym->attr.pointer && new_var->expr->ref)
+      || (ref && ref->next) || (ref && ref->u.c.sym->attr.allocatable))
+    {
+      gfc_error ("Cannot initialize '%s' with allocatable or "
+		 "pointer attribute in the DATA statement at %C",
+		 ref ? ref->u.c.sym->name : sym->name);
+      return MATCH_ERROR;
+    }
+
   if (gfc_add_data (&sym->attr, sym->name, &new_var->expr->where) == FAILURE)
     return MATCH_ERROR;
 
--- /dev/null	2011-10-18 07:25:18.091653180 +0200
+++ gcc/gcc/testsuite/gfortran.dg/data_initialized_3.f90	2011-10-18 16:04:25.000000000 +0200
@@ -0,0 +1,52 @@
+! { dg-do compile }
+!
+! PR fortran/50410
+! Parts contributed by Vittorio Zecca
+!
+! DATA intialization checking was partially missing.
+
+      subroutine one()
+      type t1
+       integer g
+      end type t1
+      type(t1) :: u=t1(1)
+      data u%g /2/ ! { dg-error "is already initialized and may thus not be in the DATA statement" }
+      end
+
+      subroutine two()
+      type t2
+       integer g
+       integer, pointer :: h
+      end type t2
+      type(t2), pointer :: u
+      type(t2) :: v
+      data  v%h /null()/ ! OK
+      data  u%h /null()/ ! { dg-error "Cannot initialize 'u'" }
+      data  u%g /1/      ! { dg-error "Cannot initialize 'u'" }
+      end
+
+      subroutine three()
+      integer, pointer :: u
+      data u /null()/
+      data u /1/ ! { dg-error "NULL.. initialization expected in DATA statement" }
+      end
+
+      module m
+        type t
+          integer :: a  = 7
+        end type t
+        type t2
+          integer :: b
+        end type t2
+      contains
+        subroutine four()
+           implicit type(t)(x), type(t2)(y)
+           DATA x%a/8/ ! { dg-error "has a default initializer and may thus not be in the DATA statement" }
+        end subroutine
+
+        subroutine five()
+          implicit type(t)(x), type(t2)(y)
+          DATA y%b/5/
+          type(t2) :: y = t2(7) ! { dg-error "initializer already appears in a DATA statement" }
+        end subroutine
+      end module m
Index: gcc/testsuite/gfortran.dg/data_constraints_1.f90
===================================================================
--- a/gcc/testsuite/gfortran.dg/data_constraints_1.f90    (revision 180138)
+++ b/gcc/testsuite/gfortran.dg/data_constraints_1.f90    (working copy)
@@ -17,7 +17,7 @@
   integer p (m), bar
   integer, allocatable :: l(:)
   allocate (l(1))
-  data l /42/           ! { dg-error "conflicts with ALLOCATABLE" }
+  data l /42/           ! { dg-error "Cannot initialize .l. with allocatable or pointer attribute in the DATA statement" }
   data p(1) /1/         ! { dg-error "non-constant array in DATA" }
   data q /1/            ! { dg-error "Host associated variable" }
   data m /1/            ! { dg-error "conflicts with DUMMY attribute" }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]