public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469
@ 2021-08-24 20:36 Harald Anlauf
  2021-08-31 19:05 ` *PING* " Harald Anlauf
  2021-09-02 10:21 ` Tobias Burnus
  0 siblings, 2 replies; 10+ messages in thread
From: Harald Anlauf @ 2021-08-24 20:36 UTC (permalink / raw)
  To: fortran, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 611 bytes --]

Dear Fortranners,

here's a pretty obvious one: we didn't properly check the arguments
for intrinsics when these had to be ALLOCATABLE and in the case that
argument was a coarray object.  Simple solution: just reuse a check
that was used for pointer etc.

Regtested on x86_64-pc-linux-gnu.  OK for mainline / backports?

Thanks,
Harald


Fortran - extend allocatable_check to coarrays

gcc/fortran/ChangeLog:

	PR fortran/93834
	* check.c (allocatable_check): A coindexed array element is not an
	allocatable object.

gcc/testsuite/ChangeLog:

	PR fortran/93834
	* gfortran.dg/coarray_allocated.f90: New test.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: pr93834.patch --]
[-- Type: text/x-patch, Size: 1033 bytes --]

diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
index 851af1b30dc..a293a7b9592 100644
--- a/gcc/fortran/check.c
+++ b/gcc/fortran/check.c
@@ -983,6 +983,14 @@ allocatable_check (gfc_expr *e, int n)
       return false;
     }

+  if (attr.codimension && gfc_is_coindexed (e))
+    {
+      gfc_error ("%qs argument of %qs intrinsic at %L shall not be "
+		 "coindexed", gfc_current_intrinsic_arg[n]->name,
+		 gfc_current_intrinsic, &e->where);
+      return false;
+    }
+
   return true;
 }

diff --git a/gcc/testsuite/gfortran.dg/coarray_allocated.f90 b/gcc/testsuite/gfortran.dg/coarray_allocated.f90
new file mode 100644
index 00000000000..70e865c94ac
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray_allocated.f90
@@ -0,0 +1,9 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib" }
+! PR fortran/93834 - ICE in trans_caf_is_present
+
+program p
+  integer, allocatable :: a[:]
+  print *, allocated (a)
+  print *, allocated (a[1]) ! { dg-error "shall not be coindexed" }
+end

^ permalink raw reply	[flat|nested] 10+ messages in thread

* *PING* [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469
  2021-08-24 20:36 [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469 Harald Anlauf
@ 2021-08-31 19:05 ` Harald Anlauf
  2021-09-02 10:21 ` Tobias Burnus
  1 sibling, 0 replies; 10+ messages in thread
From: Harald Anlauf @ 2021-08-31 19:05 UTC (permalink / raw)
  To: Harald Anlauf; +Cc: fortran, gcc-patches

PING!

> Gesendet: Dienstag, 24. August 2021 um 22:36 Uhr
> Von: "Harald Anlauf" <anlauf@gmx.de>
> An: "fortran" <fortran@gcc.gnu.org>, "gcc-patches" <gcc-patches@gcc.gnu.org>
> Betreff: [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469
>
> Dear Fortranners,
>
> here's a pretty obvious one: we didn't properly check the arguments
> for intrinsics when these had to be ALLOCATABLE and in the case that
> argument was a coarray object.  Simple solution: just reuse a check
> that was used for pointer etc.
>
> Regtested on x86_64-pc-linux-gnu.  OK for mainline / backports?
>
> Thanks,
> Harald
>
>
> Fortran - extend allocatable_check to coarrays
>
> gcc/fortran/ChangeLog:
>
> 	PR fortran/93834
> 	* check.c (allocatable_check): A coindexed array element is not an
> 	allocatable object.
>
> gcc/testsuite/ChangeLog:
>
> 	PR fortran/93834
> 	* gfortran.dg/coarray_allocated.f90: New test.
>
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469
  2021-08-24 20:36 [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469 Harald Anlauf
  2021-08-31 19:05 ` *PING* " Harald Anlauf
@ 2021-09-02 10:21 ` Tobias Burnus
  2021-09-02 18:36   ` Harald Anlauf
  1 sibling, 1 reply; 10+ messages in thread
From: Tobias Burnus @ 2021-09-02 10:21 UTC (permalink / raw)
  To: Harald Anlauf, fortran, gcc-patches

Hi Harald,

On 24.08.21 22:36, Harald Anlauf via Fortran wrote:
> here's a pretty obvious one: we didn't properly check the arguments
> for intrinsics when these had to be ALLOCATABLE and in the case that
> argument was a coarray object.  Simple solution: just reuse a check
> that was used for pointer etc.
>
> Regtested on x86_64-pc-linux-gnu.  OK for mainline / backports?
...
>       PR fortran/93834
>       * check.c (allocatable_check): A coindexed array element is not an
>       allocatable object.
First, I think the patch does not do what's on its label:
> +  if (attr.codimension && gfc_is_coindexed (e))
> +    {

Consider:

type t
   integer, allocatable :: a
end type t

type(t) :: var[*]
print *, allocated(var%a)
print *, allocated(var[1]%a)
end

I think pointer has a likewise issue.
It should be sufficient to get rid of the
attr.codimension.

  * * *

Note regarding pointers: F2018:C1542 also does not
apply to intrinsics, cf. note below C1542 (quoted below).

  * * *

By itself, I do not see why accessing the value of a
coindexed variable is a problem – just (de)allocating it should
cause problems.

With pointers, undefined might be an additional issue.

Thus, while
  allocate( coindexed object )
has issues and is invalid – all refs to F2018:
  C950 (R932) An allocate-object shall not be a coindexed object.

I do not see why
  allocated ( ...)
should be invalid; in particular, just a a NULL value check is needed.

Likewise for
  associated  ( )

Besides exceptions for polymorphic allocatables, I find:

C1537 An actual argument that is a coindexed object shall not have a pointer ultimate component.

C1542 The actual argument corresponding to a dummy pointer shall not be a coindexed object.
Note 1: Constraint C1542 does not apply to any intrinsic procedure because an intrinsic procedure is defined in
terms of its actual arguments.

For allocatables, there is:
"If the actual argument is a coindexed object with an allocatable ultimate
component, the dummy argument shall have the INTENT (IN) or the VALUE attribute."


Tobias

-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469
  2021-09-02 10:21 ` Tobias Burnus
@ 2021-09-02 18:36   ` Harald Anlauf
  2021-09-07  8:02     ` Tobias Burnus
  0 siblings, 1 reply; 10+ messages in thread
From: Harald Anlauf @ 2021-09-02 18:36 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: fortran, gcc-patches

Hi Tobias,

> Consider:
> 
> type t
>    integer, allocatable :: a
> end type t
> 
> type(t) :: var[*]
> print *, allocated(var%a)
> print *, allocated(var[1]%a)
> end

what is the problem here?  Can you elaborate?

BTW: Intel accepts it, we (currently) accept it, my patch does not change anything.

> I think pointer has a likewise issue.
> It should be sufficient to get rid of the
> attr.codimension.

???

>   * * *
> 
> Note regarding pointers: F2018:C1542 also does not
> apply to intrinsics, cf. note below C1542 (quoted below).
> 
>   * * *
> 
> By itself, I do not see why accessing the value of a
> coindexed variable is a problem – just (de)allocating it should
> cause problems.
> 
> With pointers, undefined might be an additional issue.
> 
> Thus, while
>   allocate( coindexed object )
> has issues and is invalid – all refs to F2018:
>   C950 (R932) An allocate-object shall not be a coindexed object.
> 
> I do not see why
>   allocated ( ...)
> should be invalid; in particular, just a a NULL value check is needed.
> 
> Likewise for
>   associated  ( )
> 
> Besides exceptions for polymorphic allocatables, I find:
> 
> C1537 An actual argument that is a coindexed object shall not have a pointer ultimate component.
> 
> C1542 The actual argument corresponding to a dummy pointer shall not be a coindexed object.
> Note 1: Constraint C1542 does not apply to any intrinsic procedure because an intrinsic procedure is defined in
> terms of its actual arguments.
> 
> For allocatables, there is:
> "If the actual argument is a coindexed object with an allocatable ultimate
> component, the dummy argument shall have the INTENT (IN) or the VALUE attribute."

I am afraid you lost me here.  There are other PRs involving coarrays.
Are you suggesting I should solve them all?

Withdrawing the patch.

Harald


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469
  2021-09-02 18:36   ` Harald Anlauf
@ 2021-09-07  8:02     ` Tobias Burnus
  2021-09-07 14:33       ` [Patch] Fortran: Handle allocated() with coindexed scalars [PR93834] (was: [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469) Tobias Burnus
  0 siblings, 1 reply; 10+ messages in thread
From: Tobias Burnus @ 2021-09-07  8:02 UTC (permalink / raw)
  To: Harald Anlauf, Tobias Burnus; +Cc: fortran, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2259 bytes --]

Hi Harald,

I spend yesterday about two hours with this. Now I am still
tired but understand more. I think the confusion between the
two of us is due to wording and in which directions the
thoughts then go:


Talking about coindexed, all of a[i], b[i]%c and c%d[i] are
coindexed and there are many constraints like "shall not be
a coindexed variable" – which then rejects all of those.
That's what I was thinking of.

I think your starting point is that while ('a' = allocatable)
   a, b%a, c[5]%d(1)%a
are ALLOCATABLE, adding a subobject reference such as
   a(:), b%a(:,:), c[5]%d(1)%a(:,:,:)
makes the variable no longer allocatable.
I think that's what you were thinking of.

We then both argued along those different lines – which caused
the confusion as we both thought we talked about the same.


While those cases are clear, the question is whether
   a[i] or b%a[i]
is allocatable or not – assuming that 'a' is a scalar.
(For an array, '(:)' has to appear before the image-selector,
which in turn makes it nonallocatable.)


I tried to pinpoint the words for this in the standard – and
failed. I think I need a "how to read the Fortran standard" 101
and some long time actually reading it :-(

Malcolm has answered me – and he believes (but only offhand) that
   a[i]  and  b%a[i]
_are_ allocatable. See (6) at
https://mailman.j3-fortran.org/pipermail/j3/2021-September/013322.html


This implies that
   if ( allocated (a[i]) .and. allocated (b%a[i]) ) stop 1
is valid.

However, I do note that coarray allocatables have to be collectively
(de)allocated, therefore
   allocated (a[i]) .and. allocated (b%a[i])
is equivalent to
   allocated (a) .and. allocated (b%a)
at least assuming that no image has failed.


First: Does this answer all the questions you had and resolved the
confusion?
Secondly, do you agree about the last bits of the analysis?
Thirdly, what do you think of the attached patch?

Tobias

-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

[-- Attachment #2: pr83734-alloc-coarray.diff --]
[-- Type: text/x-patch, Size: 4829 bytes --]

Fortran: Handle allocated() with coindexed scalars [PR93834]

2021-09-07  Harald Anlauf  <anlauf@gmx.de>
	    Tobias Burnus  <tobias@codesourcery.com>

While for an allocatable 'array', 'array(:)' and 'array(:)[1]' are
not allocatable, it is believed that not only 'scalar' but also
'scalar[1]' is allocatable.  However, coarrays are collectively
established/allocated; thus, 'allocated(scalar[i])' is equivalent
to 'allocated(scalar)'. [At least when assuming that 'i' does not
refer to a failed image.]

	PR fortran/93834
gcc/fortran/ChangeLog:

	* trans-intrinsic.c (gfc_conv_allocated): Cleanup. Handle
	coindexed scalar coarrays.

gcc/testsuite/ChangeLog:

	* gfortran.dg/coarray_allocated.f90: New test.

diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 46670baae55..6a7a86d245a 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -8887,50 +8887,64 @@ caf_this_image_ref (gfc_ref *ref)
 static void
 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
 {
-  gfc_actual_arglist *arg1;
   gfc_se arg1se;
   tree tmp;
-  symbol_attribute caf_attr;
+  bool coindexed_caf_comp = false;
 
-  gfc_init_se (&arg1se, NULL);
-  arg1 = expr->value.function.actual;
+  expr = expr->value.function.actual->expr;
 
-  if (arg1->expr->ts.type == BT_CLASS)
+  gfc_init_se (&arg1se, NULL);
+  if (expr->ts.type == BT_CLASS)
     {
       /* Make sure that class array expressions have both a _data
 	 component reference and an array reference....  */
-      if (CLASS_DATA (arg1->expr)->attr.dimension)
-	gfc_add_class_array_ref (arg1->expr);
+      if (CLASS_DATA (expr)->attr.dimension)
+	gfc_add_class_array_ref (expr);
       /* .... whilst scalars only need the _data component.  */
       else
-	gfc_add_data_component (arg1->expr);
+	gfc_add_data_component (expr);
     }
 
-  /* When arg1 references an allocatable component in a coarray, then call
+  /* When expr references an allocatable component in a coarray, then call
      the caf-library function caf_is_present ().  */
-  if (flag_coarray == GFC_FCOARRAY_LIB && arg1->expr->expr_type == EXPR_FUNCTION
-      && arg1->expr->value.function.isym
-      && arg1->expr->value.function.isym->id == GFC_ISYM_CAF_GET)
-    caf_attr = gfc_caf_attr (arg1->expr->value.function.actual->expr);
-  else
-    gfc_clear_attr (&caf_attr);
-  if (flag_coarray == GFC_FCOARRAY_LIB && caf_attr.codimension
-      && !caf_this_image_ref (arg1->expr->value.function.actual->expr->ref))
-    tmp = trans_caf_is_present (se, arg1->expr->value.function.actual->expr);
+  if (flag_coarray == GFC_FCOARRAY_LIB && expr->expr_type == EXPR_FUNCTION
+      && expr->value.function.isym
+      && expr->value.function.isym->id == GFC_ISYM_CAF_GET)
+    {
+      expr = expr->value.function.actual->expr;
+      if (caf_this_image_ref (expr->ref))
+	coindexed_caf_comp = false;  /* Local access. */
+      else if (gfc_expr_attr (expr).codimension)
+	{
+	  /* Last partref is the coindexed coarray. As coarrays are collectively
+	     (de)allocated, the allocation status must be the same as the one of
+	     the local allocation.  Convert to local access. */
+	  for (gfc_ref *ref = expr->ref; ref; ref = ref->next)
+	    if (ref->type == REF_ARRAY && ref->u.ar.codimen)
+	      {
+		for (int i = ref->u.ar.dimen;
+		     i < ref->u.ar.dimen + ref->u.ar.codimen; ++i)
+		ref->u.ar.dimen_type[i] = DIMEN_THIS_IMAGE;
+		break;
+	      }
+	}
+    }
+  if (coindexed_caf_comp)
+    tmp = trans_caf_is_present (se, expr);
   else
     {
-      if (arg1->expr->rank == 0)
+      if (expr->rank == 0)
 	{
 	  /* Allocatable scalar.  */
 	  arg1se.want_pointer = 1;
-	  gfc_conv_expr (&arg1se, arg1->expr);
+	  gfc_conv_expr (&arg1se, expr);
 	  tmp = arg1se.expr;
 	}
       else
 	{
 	  /* Allocatable array.  */
 	  arg1se.descriptor_only = 1;
-	  gfc_conv_expr_descriptor (&arg1se, arg1->expr);
+	  gfc_conv_expr_descriptor (&arg1se, expr);
 	  tmp = gfc_conv_descriptor_data_get (arg1se.expr);
 	}
 
diff --git a/gcc/testsuite/gfortran.dg/coarray_allocated.f90 b/gcc/testsuite/gfortran.dg/coarray_allocated.f90
new file mode 100644
index 00000000000..dcd334b9e30
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray_allocated.f90
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib -fdump-tree-original" }
+! PR fortran/93834 - ICE in trans_caf_is_present
+
+program p
+  type t
+    integer, allocatable :: x[:,:,:]
+  end type t
+  integer, allocatable :: a[:]
+  type(t) :: c
+  if (allocated (a)) stop 1
+  if (allocated (c%x)) stop 2
+
+  if (allocated (a[1])) stop 4
+  if (allocated (c%x[1,2,3])) stop 5
+end
+
+! { dg-final { scan-tree-dump-times "a.data != 0B" 2 "original" } }
+! { dg-final { scan-tree-dump-times "c.x.data != 0B" 2 "original" } }
+! { dg-final { scan-tree-dump-not "_gfortran_caf_get" "original" } }

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Patch] Fortran: Handle allocated() with coindexed scalars [PR93834] (was: [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469)
  2021-09-07  8:02     ` Tobias Burnus
@ 2021-09-07 14:33       ` Tobias Burnus
  2021-09-07 18:15         ` Harald Anlauf
                           ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Tobias Burnus @ 2021-09-07 14:33 UTC (permalink / raw)
  To: Harald Anlauf; +Cc: fortran, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2940 bytes --]

Now I actually tested the patch – and fixed some issues.

OK? – It does add support for 'allocated(a[i])' by treating
it as 'allocated(a)', as 'a' must be collectively allocated
("established") on all images of the team.*

'a[i]' is (probably) an allocatable, following Malcolm in
answer to my question to the J3-list as linked below.

Tobias

* Ignoring issues related to failed images. It could
also be handled by fetching 'a' from the remote
image, but I am not sure that's better in terms of
handling failed images.

PS:
On 07.09.21 10:02, Tobias Burnus wrote:
> Hi Harald,
>
> I spend yesterday about two hours with this. Now I am still
> tired but understand more. I think the confusion between the
> two of us is due to wording and in which directions the
> thoughts then go:
>
>
> Talking about coindexed, all of a[i], b[i]%c and c%d[i] are
> coindexed and there are many constraints like "shall not be
> a coindexed variable" – which then rejects all of those.
> That's what I was thinking of.
>
> I think your starting point is that while ('a' = allocatable)
>   a, b%a, c[5]%d(1)%a
> are ALLOCATABLE, adding a subobject reference such as
>   a(:), b%a(:,:), c[5]%d(1)%a(:,:,:)
> makes the variable no longer allocatable.
> I think that's what you were thinking of.
>
> We then both argued along those different lines – which caused
> the confusion as we both thought we talked about the same.
>
>
> While those cases are clear, the question is whether
>   a[i] or b%a[i]
> is allocatable or not – assuming that 'a' is a scalar.
> (For an array, '(:)' has to appear before the image-selector,
> which in turn makes it nonallocatable.)
>
>
> I tried to pinpoint the words for this in the standard – and
> failed. I think I need a "how to read the Fortran standard" 101
> and some long time actually reading it :-(
>
> Malcolm has answered me – and he believes (but only offhand) that
>   a[i]  and  b%a[i]
> _are_ allocatable. See (6) at
> https://mailman.j3-fortran.org/pipermail/j3/2021-September/013322.html
>
>
> This implies that
>   if ( allocated (a[i]) .and. allocated (b%a[i]) ) stop 1
> is valid.
>
> However, I do note that coarray allocatables have to be collectively
> (de)allocated, therefore
>   allocated (a[i]) .and. allocated (b%a[i])
> is equivalent to
>   allocated (a) .and. allocated (b%a)
> at least assuming that no image has failed.
>
>
> First: Does this answer all the questions you had and resolved the
> confusion?
> Secondly, do you agree about the last bits of the analysis?
> Thirdly, what do you think of the attached patch?
>
> Tobias
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

[-- Attachment #2: pr83734-alloc-coarray-v2.diff --]
[-- Type: text/x-patch, Size: 4734 bytes --]

Fortran: Handle allocated() with coindexed scalars [PR93834]

2021-09-07  Harald Anlauf  <anlauf@gmx.de>
	    Tobias Burnus  <tobias@codesourcery.com>

While for an allocatable 'array', 'array(:)' and 'array(:)[1]' are
not allocatable, it is believed that not only 'scalar' but also
'scalar[1]' is allocatable.  However, coarrays are collectively
established/allocated; thus, 'allocated(scalar[i])' is equivalent
to 'allocated(scalar)'. [At least when assuming that 'i' does not
refer to a failed image.]

	PR fortran/93834
gcc/fortran/ChangeLog:

	* trans-intrinsic.c (gfc_conv_allocated): Cleanup. Handle
	coindexed scalar coarrays.

gcc/testsuite/ChangeLog:

	* gfortran.dg/coarray_allocated.f90: New test.

diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 46670baae55..c9d1aace33e 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -8887,50 +8887,63 @@ caf_this_image_ref (gfc_ref *ref)
 static void
 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
 {
-  gfc_actual_arglist *arg1;
   gfc_se arg1se;
   tree tmp;
-  symbol_attribute caf_attr;
+  bool coindexed_caf_comp = false;
+  gfc_expr *e = expr->value.function.actual->expr;
 
   gfc_init_se (&arg1se, NULL);
-  arg1 = expr->value.function.actual;
-
-  if (arg1->expr->ts.type == BT_CLASS)
+  if (e->ts.type == BT_CLASS)
     {
       /* Make sure that class array expressions have both a _data
 	 component reference and an array reference....  */
-      if (CLASS_DATA (arg1->expr)->attr.dimension)
-	gfc_add_class_array_ref (arg1->expr);
+      if (CLASS_DATA (e)->attr.dimension)
+	gfc_add_class_array_ref (e);
       /* .... whilst scalars only need the _data component.  */
       else
-	gfc_add_data_component (arg1->expr);
+	gfc_add_data_component (e);
     }
 
-  /* When arg1 references an allocatable component in a coarray, then call
+  /* When 'e' references an allocatable component in a coarray, then call
      the caf-library function caf_is_present ().  */
-  if (flag_coarray == GFC_FCOARRAY_LIB && arg1->expr->expr_type == EXPR_FUNCTION
-      && arg1->expr->value.function.isym
-      && arg1->expr->value.function.isym->id == GFC_ISYM_CAF_GET)
-    caf_attr = gfc_caf_attr (arg1->expr->value.function.actual->expr);
-  else
-    gfc_clear_attr (&caf_attr);
-  if (flag_coarray == GFC_FCOARRAY_LIB && caf_attr.codimension
-      && !caf_this_image_ref (arg1->expr->value.function.actual->expr->ref))
-    tmp = trans_caf_is_present (se, arg1->expr->value.function.actual->expr);
+  if (flag_coarray == GFC_FCOARRAY_LIB && e->expr_type == EXPR_FUNCTION
+      && e->value.function.isym
+      && e->value.function.isym->id == GFC_ISYM_CAF_GET)
+    {
+      e = e->value.function.actual->expr;
+      if (gfc_expr_attr (e).codimension)
+	{
+	  /* Last partref is the coindexed coarray. As coarrays are collectively
+	     (de)allocated, the allocation status must be the same as the one of
+	     the local allocation.  Convert to local access. */
+	  for (gfc_ref *ref = e->ref; ref; ref = ref->next)
+	    if (ref->type == REF_ARRAY && ref->u.ar.codimen)
+	      {
+		for (int i = ref->u.ar.dimen;
+		     i < ref->u.ar.dimen + ref->u.ar.codimen; ++i)
+		ref->u.ar.dimen_type[i] = DIMEN_THIS_IMAGE;
+		break;
+	      }
+	}
+      else if (!caf_this_image_ref (e->ref))
+	coindexed_caf_comp = true;
+    }
+  if (coindexed_caf_comp)
+    tmp = trans_caf_is_present (se, e);
   else
     {
-      if (arg1->expr->rank == 0)
+      if (e->rank == 0)
 	{
 	  /* Allocatable scalar.  */
 	  arg1se.want_pointer = 1;
-	  gfc_conv_expr (&arg1se, arg1->expr);
+	  gfc_conv_expr (&arg1se, e);
 	  tmp = arg1se.expr;
 	}
       else
 	{
 	  /* Allocatable array.  */
 	  arg1se.descriptor_only = 1;
-	  gfc_conv_expr_descriptor (&arg1se, arg1->expr);
+	  gfc_conv_expr_descriptor (&arg1se, e);
 	  tmp = gfc_conv_descriptor_data_get (arg1se.expr);
 	}
 
diff --git a/gcc/testsuite/gfortran.dg/coarray_allocated.f90 b/gcc/testsuite/gfortran.dg/coarray_allocated.f90
new file mode 100644
index 00000000000..dcd334b9e30
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray_allocated.f90
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-fcoarray=lib -fdump-tree-original" }
+! PR fortran/93834 - ICE in trans_caf_is_present
+
+program p
+  type t
+    integer, allocatable :: x[:,:,:]
+  end type t
+  integer, allocatable :: a[:]
+  type(t) :: c
+  if (allocated (a)) stop 1
+  if (allocated (c%x)) stop 2
+
+  if (allocated (a[1])) stop 4
+  if (allocated (c%x[1,2,3])) stop 5
+end
+
+! { dg-final { scan-tree-dump-times "a.data != 0B" 2 "original" } }
+! { dg-final { scan-tree-dump-times "c.x.data != 0B" 2 "original" } }
+! { dg-final { scan-tree-dump-not "_gfortran_caf_get" "original" } }

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Patch] Fortran: Handle allocated() with coindexed scalars [PR93834] (was: [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469)
  2021-09-07 14:33       ` [Patch] Fortran: Handle allocated() with coindexed scalars [PR93834] (was: [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469) Tobias Burnus
@ 2021-09-07 18:15         ` Harald Anlauf
  2021-09-16 12:26         ` PING – " Tobias Burnus
       [not found]         ` <sig181$fc9$1@ciao.gmane.io>
  2 siblings, 0 replies; 10+ messages in thread
From: Harald Anlauf @ 2021-09-07 18:15 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: fortran, gcc-patches

Hi Tobias,

I think I can follow now what you are thinking, and I also had some
thoughts about what you be done in principle.

I was struggling the way I did because of:

(1) Intel rejects the code in the PR.  For my previous patch,

% ifort coarray_allocated.f90 -coarray
coarray_allocated.f90(8): error #7364: The argument to the ALLOCATED intrinsic cannot be a coindexed object.   [A]
  print *, allocated (a[1]) ! { dg-error "shall not be coindexed" }
----------------------^
compilation aborted for coarray_allocated.f90 (code 1)


(2) F2018: 16.9.11  ALLOCATED (ARRAY) or ALLOCATED (SCALAR)

Arguments.
ARRAY   shall be an allocatable array.
SCALAR  shall be an allocatable scalar.


(3) F2018: 9.4  Scalars

9.4.3 Coindexed named objects
A coindexed-named-object is a named scalar coarray variable followed by an image selector.

F2018: 9.5  Arrays (or 9.4  Scalars)

F2018: 9.6 Image selectors
An image selector determines the image index for a coindexed object.


Those are the sources of information I had, and which I interpreted in
the way that even if A is an allocatable coarray (scalar or array),
when adding an image selector, like in A[N], that object would not
satisfy the requirements for the ALLOCATED intrinsic.  It also doesn't
say coarray here.

I really didn't think about the synchronization stuff here.

I also didn't read the section on the ALLOCATE statement, but in fact
there is the following (probably in line with your argument):

9.7.1.2  Execution of an ALLOCATE statement

"The coarray shall not become allocated on an image unless it is
 successfully allocated on all active images in this team."

and the following note which says:

"When an image executes an ALLOCATE statement, communication is not
 necessarily involved apart from any required for synchronization. ..."

So a dirty shortcut could be allowed if the ALLOCATED() is considered valid.

Harald

> Gesendet: Dienstag, 07. September 2021 um 16:33 Uhr
> Von: "Tobias Burnus" <tobias@codesourcery.com>
> An: "Harald Anlauf" <anlauf@gmx.de>
> Cc: "fortran" <fortran@gcc.gnu.org>, "gcc-patches" <gcc-patches@gcc.gnu.org>
> Betreff: [Patch] Fortran: Handle allocated() with coindexed scalars [PR93834] (was: [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469)
>
> Now I actually tested the patch – and fixed some issues.
> 
> OK? – It does add support for 'allocated(a[i])' by treating
> it as 'allocated(a)', as 'a' must be collectively allocated
> ("established") on all images of the team.*
> 
> 'a[i]' is (probably) an allocatable, following Malcolm in
> answer to my question to the J3-list as linked below.
> 
> Tobias
> 
> * Ignoring issues related to failed images. It could
> also be handled by fetching 'a' from the remote
> image, but I am not sure that's better in terms of
> handling failed images.
> 
> PS:
> On 07.09.21 10:02, Tobias Burnus wrote:
> > Hi Harald,
> >
> > I spend yesterday about two hours with this. Now I am still
> > tired but understand more. I think the confusion between the
> > two of us is due to wording and in which directions the
> > thoughts then go:
> >
> >
> > Talking about coindexed, all of a[i], b[i]%c and c%d[i] are
> > coindexed and there are many constraints like "shall not be
> > a coindexed variable" – which then rejects all of those.
> > That's what I was thinking of.
> >
> > I think your starting point is that while ('a' = allocatable)
> >   a, b%a, c[5]%d(1)%a
> > are ALLOCATABLE, adding a subobject reference such as
> >   a(:), b%a(:,:), c[5]%d(1)%a(:,:,:)
> > makes the variable no longer allocatable.
> > I think that's what you were thinking of.
> >
> > We then both argued along those different lines – which caused
> > the confusion as we both thought we talked about the same.
> >
> >
> > While those cases are clear, the question is whether
> >   a[i] or b%a[i]
> > is allocatable or not – assuming that 'a' is a scalar.
> > (For an array, '(:)' has to appear before the image-selector,
> > which in turn makes it nonallocatable.)
> >
> >
> > I tried to pinpoint the words for this in the standard – and
> > failed. I think I need a "how to read the Fortran standard" 101
> > and some long time actually reading it :-(
> >
> > Malcolm has answered me – and he believes (but only offhand) that
> >   a[i]  and  b%a[i]
> > _are_ allocatable. See (6) at
> > https://mailman.j3-fortran.org/pipermail/j3/2021-September/013322.html
> >
> >
> > This implies that
> >   if ( allocated (a[i]) .and. allocated (b%a[i]) ) stop 1
> > is valid.
> >
> > However, I do note that coarray allocatables have to be collectively
> > (de)allocated, therefore
> >   allocated (a[i]) .and. allocated (b%a[i])
> > is equivalent to
> >   allocated (a) .and. allocated (b%a)
> > at least assuming that no image has failed.
> >
> >
> > First: Does this answer all the questions you had and resolved the
> > confusion?
> > Secondly, do you agree about the last bits of the analysis?
> > Thirdly, what do you think of the attached patch?
> >
> > Tobias
> -----------------
> Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* PING – Re: [Patch] Fortran: Handle allocated() with coindexed scalars [PR93834] (was: [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469)
  2021-09-07 14:33       ` [Patch] Fortran: Handle allocated() with coindexed scalars [PR93834] (was: [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469) Tobias Burnus
  2021-09-07 18:15         ` Harald Anlauf
@ 2021-09-16 12:26         ` Tobias Burnus
  2021-09-22 16:55           ` PING**2 " Tobias Burnus
       [not found]         ` <sig181$fc9$1@ciao.gmane.io>
  2 siblings, 1 reply; 10+ messages in thread
From: Tobias Burnus @ 2021-09-16 12:26 UTC (permalink / raw)
  To: gcc-patches, fortran; +Cc: Harald Anlauf

Patch PING – see comment in the follow-up email of the patch email - and
in the email(s) before in that thread.

Tobias

On 07.09.21 16:33, Tobias Burnus wrote:
> Now I actually tested the patch – and fixed some issues.
>
> OK? – It does add support for 'allocated(a[i])' by treating
> it as 'allocated(a)', as 'a' must be collectively allocated
> ("established") on all images of the team.*
>
> 'a[i]' is (probably) an allocatable, following Malcolm in
> answer to my question to the J3-list as linked below.
>
> Tobias
>
> * Ignoring issues related to failed images. It could
> also be handled by fetching 'a' from the remote
> image, but I am not sure that's better in terms of
> handling failed images.
>
> PS:
> On 07.09.21 10:02, Tobias Burnus wrote:
>> Hi Harald,
>>
>> I spend yesterday about two hours with this. Now I am still
>> tired but understand more. I think the confusion between the
>> two of us is due to wording and in which directions the
>> thoughts then go:
>>
>>
>> Talking about coindexed, all of a[i], b[i]%c and c%d[i] are
>> coindexed and there are many constraints like "shall not be
>> a coindexed variable" – which then rejects all of those.
>> That's what I was thinking of.
>>
>> I think your starting point is that while ('a' = allocatable)
>>   a, b%a, c[5]%d(1)%a
>> are ALLOCATABLE, adding a subobject reference such as
>>   a(:), b%a(:,:), c[5]%d(1)%a(:,:,:)
>> makes the variable no longer allocatable.
>> I think that's what you were thinking of.
>>
>> We then both argued along those different lines – which caused
>> the confusion as we both thought we talked about the same.
>>
>>
>> While those cases are clear, the question is whether
>>   a[i] or b%a[i]
>> is allocatable or not – assuming that 'a' is a scalar.
>> (For an array, '(:)' has to appear before the image-selector,
>> which in turn makes it nonallocatable.)
>>
>>
>> I tried to pinpoint the words for this in the standard – and
>> failed. I think I need a "how to read the Fortran standard" 101
>> and some long time actually reading it :-(
>>
>> Malcolm has answered me – and he believes (but only offhand) that
>>   a[i]  and  b%a[i]
>> _are_ allocatable. See (6) at
>> https://mailman.j3-fortran.org/pipermail/j3/2021-September/013322.html
>>
>>
>> This implies that
>>   if ( allocated (a[i]) .and. allocated (b%a[i]) ) stop 1
>> is valid.
>>
>> However, I do note that coarray allocatables have to be collectively
>> (de)allocated, therefore
>>   allocated (a[i]) .and. allocated (b%a[i])
>> is equivalent to
>>   allocated (a) .and. allocated (b%a)
>> at least assuming that no image has failed.
>>
>>
>> First: Does this answer all the questions you had and resolved the
>> confusion?
>> Secondly, do you agree about the last bits of the analysis?
>> Thirdly, what do you think of the attached patch?
>>
>> Tobias
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: PING**2 – Re: [Patch] Fortran: Handle allocated() with coindexed scalars [PR93834] (was: [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469)
  2021-09-16 12:26         ` PING – " Tobias Burnus
@ 2021-09-22 16:55           ` Tobias Burnus
  0 siblings, 0 replies; 10+ messages in thread
From: Tobias Burnus @ 2021-09-22 16:55 UTC (permalink / raw)
  To: gcc-patches, fortran; +Cc: Harald Anlauf, Thomas Koenig

(1) PING**2

(2) However, as it causes for others test-suite fails,* the
      https://gcc.gnu.org/pipermail/gcc-patches/2021-September/579965.html
      [Patch] Fortran: Improve -Wmissing-include-dirs warnings [PR55534]
     is probably more important.

[* I don't see it locally as it probably uses and finds directories from
the install dir; however, others see it (hundreds of tails)
including the regression tracker at
https://gcc.gnu.org/pipermail/gcc-patches/2021-September/579963.html ]

(3) Also pending is
       https://gcc.gnu.org/pipermail/gcc-patches/2021-September/579903.html
       [Patch] Fortran: Fix assumed-size to assumed-rank passing [PR94070]
     (Thanks Thomas for reviewing the auxiliary loop patch :-)

Tobias

PS: Also pending is the GFC <-> CFI descriptor conversion patch, but expect
a revised patch soon. (Fixes found issues, uses aux loop function, fixes
contiguous attribute handling, len=* with assumed-size/explicit-size arrays,
...)

On 16.09.21 14:26, Tobias Burnus wrote:
> Patch PING – see comment in the follow-up email of the patch email -
> and in the email(s) before in that thread.
>
> Tobias
>
> On 07.09.21 16:33, Tobias Burnus wrote:
>> Now I actually tested the patch – and fixed some issues.
>>
>> OK? – It does add support for 'allocated(a[i])' by treating
>> it as 'allocated(a)', as 'a' must be collectively allocated
>> ("established") on all images of the team.*
>>
>> 'a[i]' is (probably) an allocatable, following Malcolm in
>> answer to my question to the J3-list as linked below.
>>
>> Tobias
>>
>> * Ignoring issues related to failed images. It could
>> also be handled by fetching 'a' from the remote
>> image, but I am not sure that's better in terms of
>> handling failed images.
>>
>> PS:
>> On 07.09.21 10:02, Tobias Burnus wrote:
>>> Hi Harald,
>>>
>>> I spend yesterday about two hours with this. Now I am still
>>> tired but understand more. I think the confusion between the
>>> two of us is due to wording and in which directions the
>>> thoughts then go:
>>>
>>>
>>> Talking about coindexed, all of a[i], b[i]%c and c%d[i] are
>>> coindexed and there are many constraints like "shall not be
>>> a coindexed variable" – which then rejects all of those.
>>> That's what I was thinking of.
>>>
>>> I think your starting point is that while ('a' = allocatable)
>>>   a, b%a, c[5]%d(1)%a
>>> are ALLOCATABLE, adding a subobject reference such as
>>>   a(:), b%a(:,:), c[5]%d(1)%a(:,:,:)
>>> makes the variable no longer allocatable.
>>> I think that's what you were thinking of.
>>>
>>> We then both argued along those different lines – which caused
>>> the confusion as we both thought we talked about the same.
>>>
>>>
>>> While those cases are clear, the question is whether
>>>   a[i] or b%a[i]
>>> is allocatable or not – assuming that 'a' is a scalar.
>>> (For an array, '(:)' has to appear before the image-selector,
>>> which in turn makes it nonallocatable.)
>>>
>>>
>>> I tried to pinpoint the words for this in the standard – and
>>> failed. I think I need a "how to read the Fortran standard" 101
>>> and some long time actually reading it :-(
>>>
>>> Malcolm has answered me – and he believes (but only offhand) that
>>>   a[i]  and  b%a[i]
>>> _are_ allocatable. See (6) at
>>> https://mailman.j3-fortran.org/pipermail/j3/2021-September/013322.html
>>>
>>>
>>> This implies that
>>>   if ( allocated (a[i]) .and. allocated (b%a[i]) ) stop 1
>>> is valid.
>>>
>>> However, I do note that coarray allocatables have to be collectively
>>> (de)allocated, therefore
>>>   allocated (a[i]) .and. allocated (b%a[i])
>>> is equivalent to
>>>   allocated (a) .and. allocated (b%a)
>>> at least assuming that no image has failed.
>>>
>>>
>>> First: Does this answer all the questions you had and resolved the
>>> confusion?
>>> Secondly, do you agree about the last bits of the analysis?
>>> Thirdly, what do you think of the attached patch?
>>>
>>> Tobias
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Patch] Fortran: Handle allocated() with coindexed scalars [PR93834] (was: [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469)
       [not found]         ` <sig181$fc9$1@ciao.gmane.io>
@ 2021-09-23 16:56           ` Tobias Burnus
  0 siblings, 0 replies; 10+ messages in thread
From: Tobias Burnus @ 2021-09-23 16:56 UTC (permalink / raw)
  To: Harald Anlauf, fortran; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1257 bytes --]

Hi Harald,

On 22.09.21 21:47, Harald Anlauf via Fortran wrote:
> while still feeling somewhat unsure (given my previous comment
> and the discussion), I think your patch is basically OK.
>
> However, your testcase has a { dg-do compile }, so it does not
> really do any runtime tests.  Is that intended?  If so, please
> add a respective comment, or adjust the testcase.

I have now moved the testcase to coarray/ and turned it into 'dg-do run'.

To make it a bit more interesting, I added allocate/deallocate plus some
more allocate() checks. Updating the -fdump-tree-original dump scans
took a small trickery as allocate/deallocate of a coarray has some extra
inlined checks (is allocated? did malloc work?) with -fcoarray=single
but puts the burden to the library for -fcoarray=lib. Fortunately, there
is a pointless cast for 'allocatable' which made it possible to
distinguish the ==/!= 0 checks.

> Otherwise this LGTM.

Thanks for the review!

Tobias


-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

[-- Attachment #2: committed.diff --]
[-- Type: text/x-patch, Size: 6562 bytes --]

commit 1b07d9dce6c51c98d011236c3d4cd84a2ed59ba2
Author: Tobias Burnus <tobias@codesourcery.com>
Date:   Thu Sep 23 18:47:45 2021 +0200

    Fortran: Handle allocated() with coindexed scalars [PR93834]
    
    While for an allocatable 'array', 'array(:)' and 'array(:)[1]' are
    not allocatable, it is believed that not only 'scalar' but also
    'scalar[1]' is allocatable.  However, coarrays are collectively
    established/allocated; thus, 'allocated(scalar[i])' is equivalent
    to 'allocated(scalar)'. [At least when assuming that 'i' does not
    refer to a failed image.]
    
    2021-09-23  Harald Anlauf  <anlauf@gmx.de>
                Tobias Burnus  <tobias@codesourcery.com>
    
            PR fortran/93834
    gcc/fortran/ChangeLog:
    
            * trans-intrinsic.c (gfc_conv_allocated): Cleanup. Handle
            coindexed scalar coarrays.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/coarray/coarray_allocated.f90: New test.
---
 gcc/fortran/trans-intrinsic.c                      | 55 +++++++++++++---------
 .../gfortran.dg/coarray/coarray_allocated.f90      | 55 ++++++++++++++++++++++
 2 files changed, 89 insertions(+), 21 deletions(-)

diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 42a995be348..612ca41a016 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -8887,50 +8887,63 @@ caf_this_image_ref (gfc_ref *ref)
 static void
 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
 {
-  gfc_actual_arglist *arg1;
   gfc_se arg1se;
   tree tmp;
-  symbol_attribute caf_attr;
+  bool coindexed_caf_comp = false;
+  gfc_expr *e = expr->value.function.actual->expr;
 
   gfc_init_se (&arg1se, NULL);
-  arg1 = expr->value.function.actual;
-
-  if (arg1->expr->ts.type == BT_CLASS)
+  if (e->ts.type == BT_CLASS)
     {
       /* Make sure that class array expressions have both a _data
 	 component reference and an array reference....  */
-      if (CLASS_DATA (arg1->expr)->attr.dimension)
-	gfc_add_class_array_ref (arg1->expr);
+      if (CLASS_DATA (e)->attr.dimension)
+	gfc_add_class_array_ref (e);
       /* .... whilst scalars only need the _data component.  */
       else
-	gfc_add_data_component (arg1->expr);
+	gfc_add_data_component (e);
     }
 
-  /* When arg1 references an allocatable component in a coarray, then call
+  /* When 'e' references an allocatable component in a coarray, then call
      the caf-library function caf_is_present ().  */
-  if (flag_coarray == GFC_FCOARRAY_LIB && arg1->expr->expr_type == EXPR_FUNCTION
-      && arg1->expr->value.function.isym
-      && arg1->expr->value.function.isym->id == GFC_ISYM_CAF_GET)
-    caf_attr = gfc_caf_attr (arg1->expr->value.function.actual->expr);
-  else
-    gfc_clear_attr (&caf_attr);
-  if (flag_coarray == GFC_FCOARRAY_LIB && caf_attr.codimension
-      && !caf_this_image_ref (arg1->expr->value.function.actual->expr->ref))
-    tmp = trans_caf_is_present (se, arg1->expr->value.function.actual->expr);
+  if (flag_coarray == GFC_FCOARRAY_LIB && e->expr_type == EXPR_FUNCTION
+      && e->value.function.isym
+      && e->value.function.isym->id == GFC_ISYM_CAF_GET)
+    {
+      e = e->value.function.actual->expr;
+      if (gfc_expr_attr (e).codimension)
+	{
+	  /* Last partref is the coindexed coarray. As coarrays are collectively
+	     (de)allocated, the allocation status must be the same as the one of
+	     the local allocation.  Convert to local access. */
+	  for (gfc_ref *ref = e->ref; ref; ref = ref->next)
+	    if (ref->type == REF_ARRAY && ref->u.ar.codimen)
+	      {
+		for (int i = ref->u.ar.dimen;
+		     i < ref->u.ar.dimen + ref->u.ar.codimen; ++i)
+		ref->u.ar.dimen_type[i] = DIMEN_THIS_IMAGE;
+		break;
+	      }
+	}
+      else if (!caf_this_image_ref (e->ref))
+	coindexed_caf_comp = true;
+    }
+  if (coindexed_caf_comp)
+    tmp = trans_caf_is_present (se, e);
   else
     {
-      if (arg1->expr->rank == 0)
+      if (e->rank == 0)
 	{
 	  /* Allocatable scalar.  */
 	  arg1se.want_pointer = 1;
-	  gfc_conv_expr (&arg1se, arg1->expr);
+	  gfc_conv_expr (&arg1se, e);
 	  tmp = arg1se.expr;
 	}
       else
 	{
 	  /* Allocatable array.  */
 	  arg1se.descriptor_only = 1;
-	  gfc_conv_expr_descriptor (&arg1se, arg1->expr);
+	  gfc_conv_expr_descriptor (&arg1se, e);
 	  tmp = gfc_conv_descriptor_data_get (arg1se.expr);
 	}
 
diff --git a/gcc/testsuite/gfortran.dg/coarray/coarray_allocated.f90 b/gcc/testsuite/gfortran.dg/coarray/coarray_allocated.f90
new file mode 100644
index 00000000000..a423d1f126e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/coarray/coarray_allocated.f90
@@ -0,0 +1,55 @@
+! { dg-do run }
+! { dg-additional-options "-fdump-tree-original" }
+! PR fortran/93834 - ICE in trans_caf_is_present
+
+program p
+  type t
+    integer, allocatable :: x[:,:,:]
+  end type t
+  integer, allocatable :: a[:]
+  type(t) :: c
+  if (allocated (a)) stop 1
+  if (allocated (c%x)) stop 2
+
+  ! The coindexed scalar (!) variable is regarded as allocatable but
+  ! we can check the value on any image of the team as they are
+  ! established collectively.  As tested by the dump, we do it on
+  ! this_image ().
+  !
+  ! For this reason, -fcoarray=single and -fcoarray=lib give the
+  ! same result
+  if (allocated (a[1])) stop 3
+  if (allocated (c%x[1,2,3])) stop 4
+
+  ! Allocate collectively
+  allocate(a[*])
+  allocate(c%x[4,10,*])
+
+  if (.not. allocated (a)) stop 5
+  if (.not. allocated (c%x)) stop 6
+  if (.not. allocated (a[1])) stop 7
+  if (.not. allocated (c%x[1,2,3])) stop 8
+
+  ! Dellocate collectively
+  deallocate(a)
+  deallocate(c%x)
+
+  if (allocated (a)) stop 9
+  if (allocated (c%x)) stop 10
+  if (allocated (a[1])) stop 11
+  if (allocated (c%x[1,2,3])) stop 12
+end
+
+! twice == 0 for .not. allocated' (coindexed vs. not)
+! four times != for allocated (before alloc after dealloc, coindexed and not)
+
+! There are also == 0 and != 0 for (de)allocate checks with -fcoarray=single but those
+! aren't prefixed by '(integer(kind=4) *)'
+
+! { dg-final { scan-tree-dump-times "\\(integer\\(kind=4\\) \\*\\) a.data != 0B" 4 "original" } }
+! { dg-final { scan-tree-dump-times "\\(integer\\(kind=4\\) \\*\\) c.x.data != 0B" 4 "original" } }
+! { dg-final { scan-tree-dump-times "\\(integer\\(kind=4\\) \\*\\) a.data == 0B" 2 "original" } }
+! { dg-final { scan-tree-dump-times "\\(integer\\(kind=4\\) \\*\\) c.x.data == 0B" 2 "original" } }
+
+! Expected: always local access and never a call to _gfortran_caf_get
+! { dg-final { scan-tree-dump-not "caf_get" "original" } }

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-09-23 16:57 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-24 20:36 [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469 Harald Anlauf
2021-08-31 19:05 ` *PING* " Harald Anlauf
2021-09-02 10:21 ` Tobias Burnus
2021-09-02 18:36   ` Harald Anlauf
2021-09-07  8:02     ` Tobias Burnus
2021-09-07 14:33       ` [Patch] Fortran: Handle allocated() with coindexed scalars [PR93834] (was: [PATCH] PR fortran/93834 - [9/10/11/12 Regression] ICE in trans_caf_is_present, at fortran/trans-intrinsic.c:8469) Tobias Burnus
2021-09-07 18:15         ` Harald Anlauf
2021-09-16 12:26         ` PING – " Tobias Burnus
2021-09-22 16:55           ` PING**2 " Tobias Burnus
     [not found]         ` <sig181$fc9$1@ciao.gmane.io>
2021-09-23 16:56           ` Tobias Burnus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).