Fortran: improve check of pointer initialization in DATA statements
authorHarald Anlauf <anlauf@gmx.de>
Wed, 9 Feb 2022 20:54:29 +0000 (21:54 +0100)
committerHarald Anlauf <anlauf@gmx.de>
Sun, 20 Feb 2022 21:34:21 +0000 (22:34 +0100)
gcc/fortran/ChangeLog:

PR fortran/77693
* data.cc (gfc_assign_data_value): If a variable in a data
statement has the POINTER attribute, check for allowed initial
data target that is compatible with pointer assignment.
* gfortran.h (IS_POINTER): New macro.

gcc/testsuite/ChangeLog:

PR fortran/77693
* gfortran.dg/data_pointer_2.f90: New test.

gcc/fortran/data.cc
gcc/fortran/gfortran.h
gcc/testsuite/gfortran.dg/data_pointer_2.f90 [new file with mode: 0644]

index f7c9143..7a5866f 100644 (file)
@@ -618,6 +618,10 @@ gfc_assign_data_value (gfc_expr *lvalue, gfc_expr *rvalue, mpz_t index,
        gfc_convert_type (expr, &lvalue->ts, 0);
     }
 
+  if (IS_POINTER (symbol)
+      && !gfc_check_pointer_assign (lvalue, rvalue, false, true))
+    return false;
+
   if (last_con == NULL)
     symbol->value = expr;
   else
index cb136f8..f8fd1ba 100644 (file)
@@ -3897,6 +3897,9 @@ bool gfc_is_finalizable (gfc_symbol *, gfc_expr **);
         && CLASS_DATA (sym) \
         && CLASS_DATA (sym)->attr.dimension \
         && !CLASS_DATA (sym)->attr.class_pointer)
+#define IS_POINTER(sym) \
+       (sym->ts.type == BT_CLASS && sym->attr.class_ok && CLASS_DATA (sym) \
+        ? CLASS_DATA (sym)->attr.class_pointer : sym->attr.pointer)
 
 /* frontend-passes.cc */
 
diff --git a/gcc/testsuite/gfortran.dg/data_pointer_2.f90 b/gcc/testsuite/gfortran.dg/data_pointer_2.f90
new file mode 100644 (file)
index 0000000..e1677d1
--- /dev/null
@@ -0,0 +1,21 @@
+! { dg-do compile }
+! { dg-options "-O -g" }
+! PR fortran/77693 - ICE in rtl_for_decl_init
+! Contributed by G.Steinmetz
+
+program p
+  implicit none
+  complex, target  :: y    = (1.,2.)
+  complex, target  :: z(2) = (3.,4.)
+  complex, pointer :: a => y
+  complex, pointer :: b => z(1)
+  complex, pointer :: c, d, e
+  data c /NULL()/   ! Valid
+  data d /y/        ! Valid
+  data e /(1.,2.)/  ! { dg-error "Pointer assignment target" }
+  if (associated (a)) print *, a% re
+  if (associated (b)) print *, b% im
+  if (associated (c)) print *, c% re
+  if (associated (d)) print *, d% im
+  if (associated (e)) print *, e% re
+end