diff mbox series

[PR,fortran/85797] - ICE in gfc_element_size, at fortran/target-memory.c:126

Message ID 5C8EBB7F.90305@gmx.de
State New
Headers show
Series [PR,fortran/85797] - ICE in gfc_element_size, at fortran/target-memory.c:126 | expand

Commit Message

Harald Anlauf March 17, 2019, 9:26 p.m. UTC
The attached patch fixes an ICE-on-invalid code when the TRANSFER
intrinsic is being handed procedures to the SOURCE or MOLD arguments.
My reading of the standard suggests that this is not allowed:

  SOURCE shall be a scalar or array of any type.

  MOLD shall be a scalar or array of any type. ...

I was struggling for some moment with the idea that SOURCE could be
a procedure pointer (technically), but finally dismissed it.
The patch thus rejects procedures as arguments.

Regtests cleanly on x86_64-pc-linux-gnu.

OK for trunk?

Harald

2019-03-17  Harald Anlauf  <anlauf@gmx.de>

	PR fortran/85797
	* check.c (gfc_check_transfer): Reject procedures as actual
	arguments for SOURCE and MOLD of TRANSFER intrinsic.

2019-03-17  Harald Anlauf  <anlauf@gmx.de>

	PR fortran/85797
	* gfortran.dg/pr85797.f90: New test.

Index: gcc/testsuite/gfortran.dg/pr85797.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr85797.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/pr85797.f90	(working copy)
@@ -0,0 +1,22 @@
+! { dg-do compile }
+! PR fortran/85797 - ICE in gfc_element_size, at fortran/target-memory.c:126
+! Derived from original test cases by Gerhard Steinmetz
+
+module test
+contains
+  function f ()
+    f = 1.
+  end function f
+  subroutine sub ()
+  end subroutine sub
+  recursive subroutine a ()
+    integer(8) :: p
+    procedure(sub), pointer :: x => sub
+    p = transfer (sub, p)     ! { dg-error "must not be a PROCEDURE" }
+    p = transfer (p, sub)     ! { dg-error "must not be a PROCEDURE" }
+    p = transfer (f, p)       ! { dg-error "must not be a PROCEDURE" }
+    p = transfer (p, f)       ! { dg-error "must not be a PROCEDURE" }
+    c = transfer (a, b)       ! { dg-error "must not be a PROCEDURE" }
+    print *, transfer (x, x)  ! { dg-error "must not be a PROCEDURE" }
+  end subroutine a
+end module test

Comments

Thomas Koenig March 20, 2019, 4:14 p.m. UTC | #1
Hi Harald,

> My reading of the standard suggests that this is not allowed:
> 
>    SOURCE shall be a scalar or array of any type.
> 
>    MOLD shall be a scalar or array of any type. ...

I read the stanard differently.  For comparison, look at UNPACK:

# VECTOR  shall be a rank-one array of any type.

and a function result is fine there.

Also, looking at how the paragraph about MOLD continues:

# MOLD  shall be a scalar or array of any type. If it is a variable, it
# need not be defined.

The sentence starting with "If" would be redundant if MOLD could
only be a variable.

However, I am ready to be convinced otherwise :-)

Regards

	Thomas
Harald Anlauf March 20, 2019, 7:39 p.m. UTC | #2
Hi Thomas,

based on your comments I'll withdraw the patch, but read on...

On 03/20/19 17:14, Thomas Koenig wrote:
> Hi Harald,
>
>> My reading of the standard suggests that this is not allowed:
>>
>>    SOURCE shall be a scalar or array of any type.
>>
>>    MOLD shall be a scalar or array of any type. ...
>
> I read the stanard differently.  For comparison, look at UNPACK:
>
> # VECTOR  shall be a rank-one array of any type.
>
> and a function result is fine there.

If PROCEDURE is a type, then my patch is wrong.

I got rejections of several variations of the test cases by
Crayftn and Intel, which seemed to support my interpretation.

> Also, looking at how the paragraph about MOLD continues:
>
> # MOLD  shall be a scalar or array of any type. If it is a variable, it
> # need not be defined.
>
> The sentence starting with "If" would be redundant if MOLD could
> only be a variable.

No.  A constant expression for MOLD is quite useful; I use it every day.
In fact, I consider TRANSFER to be the "Swiss army knife of Fortran 95",
and we have tons on TRANSFER in our code, with MOLD being 1, [1], ["*"],
you name it...

> However, I am ready to be convinced otherwise :-)

Well, your response shows that the review process exists!

I have a slightly different approach in mind that I need to check.

Thanks for the review anyway,

Harald (not the "real" McGyver)

> Regards
>
>     Thomas
>
diff mbox series

Patch

Index: gcc/fortran/check.c
===================================================================
--- gcc/fortran/check.c	(revision 269717)
+++ gcc/fortran/check.c	(working copy)
@@ -5544,6 +5544,24 @@ 
   size_t source_size;
   size_t result_size;
 
+  /* SOURCE shall be a scalar or array of any type.  */
+  if (source->ts.type == BT_PROCEDURE)
+    {
+      gfc_error ("%<SOURCE%> argument of %<TRANSFER%> intrinsic at %L "
+                 "must not be a %s", &source->where,
+		 gfc_basic_typename (source->ts.type));
+      return false;
+    }
+
+  /* MOLD shall be a scalar or array of any type.  */
+  if (mold->ts.type == BT_PROCEDURE)
+    {
+      gfc_error ("%<MOLD%> argument of %<TRANSFER%> intrinsic at %L "
+                 "must not be a %s", &mold->where,
+		 gfc_basic_typename (mold->ts.type));
+      return false;
+    }
+
   if (mold->ts.type == BT_HOLLERITH)
     {
       gfc_error ("%<MOLD%> argument of %<TRANSFER%> intrinsic at %L must not be"
@@ -5551,6 +5569,8 @@ 
       return false;
     }
 
+  /* SIZE (optional) shall be an integer scalar.  The corresponding actual
+     argument shall not be an optional dummy argument.  */
   if (size != NULL)
     {
       if (!type_check (size, 2, BT_INTEGER))