Bug 93835 - [9/10 Regression] ICE in simplify_findloc_nodim, at fortran/simplify.c:5513
Summary: [9/10 Regression] ICE in simplify_findloc_nodim, at fortran/simplify.c:5513
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 10.0
: P4 normal
Target Milestone: 9.3
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2020-02-19 17:57 UTC by G. Steinmetz
Modified: 2020-02-26 08:19 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-02-19 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description G. Steinmetz 2020-02-19 17:57:57 UTC
Changed between 20181021 and 20181028 :


$ cat z1.f90
program p
   print *, findloc(shape(1), 1)
end


$ gfortran-9-20181021 -c z1.f90
$
$ gfortran-10-20200216 -c z1.f90
f951: internal compiler error: Segmentation fault
0xbae76f crash_signal
        ../../gcc/toplev.c:328
0x6d0d20 simplify_findloc_nodim
        ../../gcc/fortran/simplify.c:5513
0x6d9df9 gfc_simplify_findloc(gfc_expr*, gfc_expr*, gfc_expr*, gfc_expr*, gfc_expr*, gfc_expr*)
        ../../gcc/fortran/simplify.c:5779
0x6607f6 do_simplify
        ../../gcc/fortran/intrinsic.c:4638
0x66af6a gfc_intrinsic_func_interface(gfc_expr*, int)
        ../../gcc/fortran/intrinsic.c:4996
0x6c2b1e resolve_unknown_f
        ../../gcc/fortran/resolve.c:2894
0x6c2b1e resolve_function
        ../../gcc/fortran/resolve.c:3238
0x6c2b1e gfc_resolve_expr(gfc_expr*)
        ../../gcc/fortran/resolve.c:7000
0x6b9eac gfc_resolve_expr(gfc_expr*)
        ../../gcc/fortran/resolve.c:6967
0x6b9eac gfc_resolve_code(gfc_code*, gfc_namespace*)
        ../../gcc/fortran/resolve.c:11687
0x6c8d9f gfc_resolve_blocks(gfc_code*, gfc_namespace*)
        ../../gcc/fortran/resolve.c:10714
0x6b8bd8 gfc_resolve_code(gfc_code*, gfc_namespace*)
        ../../gcc/fortran/resolve.c:11677
0x6bb457 resolve_codes
        ../../gcc/fortran/resolve.c:17204
0x6bb51e gfc_resolve(gfc_namespace*)
        ../../gcc/fortran/resolve.c:17239
0x6a987c resolve_all_program_units
        ../../gcc/fortran/parse.c:6245
0x6a987c gfc_parse_file()
        ../../gcc/fortran/parse.c:6492
0x6f44ff gfc_be_parse_file
        ../../gcc/fortran/f95-lang.c:210
Comment 1 G. Steinmetz 2020-02-19 17:58:29 UTC
This analogous variant works :


$ cat z2.f90
program p
   print *, findloc([integer::], 1)
end


$ gfortran-10-20200216 z1.f90 && a.out
           0
$
Comment 2 kargls 2020-02-19 21:28:02 UTC
Patch is against svn r280157.  Someone needs to convert the example code into a testcase.  Some whitespace clean is mixed in as a bonus.

Index: gcc/fortran/simplify.c
===================================================================
--- gcc/fortran/simplify.c	(revision 280157)
+++ gcc/fortran/simplify.c	(working copy)
@@ -5497,7 +5497,7 @@ simplify_findloc_nodim (gfc_expr *result, gfc_expr *va
   bool continue_loop;
   bool ma;
 
-  for (i = 0; i<array->rank; i++)
+  for (i = 0; i < array->rank; i++)
     res[i] = -1;
 
   /* Shortcut for constant .FALSE. MASK.  */
@@ -5506,14 +5506,19 @@ simplify_findloc_nodim (gfc_expr *result, gfc_expr *va
       && !mask->value.logical)
     goto finish;
 
-  for (i = 0; i < array->rank; i++)
+  if (array->shape)
     {
-      count[i] = 0;
-      sstride[i] = (i == 0) ? 1 : sstride[i-1] * mpz_get_si (array->shape[i-1]);
-      extent[i] = mpz_get_si (array->shape[i]);
-      if (extent[i] <= 0)
-	goto finish;
+      for (i = 0; i < array->rank; i++)
+	{
+	  count[i] = 0;
+	  sstride[i] = (i == 0) ? 1 : sstride[i-1] * mpz_get_si (array->shape[i-1]);
+	  extent[i] = mpz_get_si (array->shape[i]);
+	  if (extent[i] <= 0)
+	    goto finish;
+    	}
     }
+  else
+    goto finish;
 
   continue_loop = true;
   array_ctor = gfc_constructor_first (array->value.constructor);
@@ -5540,7 +5545,7 @@ simplify_findloc_nodim (gfc_expr *result, gfc_expr *va
 
 	  if (ma && gfc_compare_expr (a, value, INTRINSIC_EQ) == 0)
 	    {
-	      for (i = 0; i<array->rank; i++)
+	      for (i = 0; i < array->rank; i++)
 		res[i] = count[i];
 	      if (!back_val)
 		goto finish;
@@ -5565,9 +5570,9 @@ simplify_findloc_nodim (gfc_expr *result, gfc_expr *va
 	} while (count[n] == extent[n]);
     }
 
- finish:
+finish:
   result_ctor = gfc_constructor_first (result->value.constructor);
-  for (i = 0; i<array->rank; i++)
+  for (i = 0; i < array->rank; i++)
     {
       gfc_expr *r_expr;
       r_expr = result_ctor->expr;
Comment 3 Martin Liška 2020-02-20 08:32:05 UTC
Started with r9-3688-g01ce9e31a02c8039.
Comment 4 markeggleston 2020-02-21 15:50:31 UTC
After applying the patch in comment 2 the ICE no longer occurs, however, it reveals an error when using the shape intrinsic with the findloc intrinsic.

program test
  print *, findloc(shape([1, 2, 3, 4]), 4)
end program

produces:

           0

i.e. 4 is not found in the array returned by shape.

shape does indeed return [ 4 ] but the expression representing the array does not have a shape defined. This is why it is necessary to check for the existence of shape in the original patch.

Adding a shape to the result expression addressed the issue and also means that the original is not required:

diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index 613fdafd1a6..59afb239af5 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -7228,6 +7228,8 @@ gfc_simplify_shape (gfc_expr *source, gfc_expr *kind)
     return NULL;
 
   result = gfc_get_array_expr (BT_INTEGER, k, &source->where);
+  result->shape = gfc_get_shape (1);
+  mpz_init (result->shape[0]);
 
   if (source->rank == 0)
     return result;
@@ -7284,6 +7286,8 @@ gfc_simplify_shape (gfc_expr *source, gfc_expr *kind)
   if (t)
     gfc_clear_shape (shape, source->rank);
 
+  mpz_set_si (result->shape[0], source->rank);
+  
   return result;
 }

There is some tidying up to do as pr77351.f90 now produces one error instead of two:

    4 |    print *, any(shape(z) /= [4,1])  ! { dg-error "shape for elemental binary" }
      |                1          2
Error: Shapes for operands at (1) and (2) are not conformable

verses:

    4 |    print *, any(shape(z) /= [4,1])  ! { dg-error "shape for elemental binary" }
      |                1
Error: Different shape for elemental binary operation at (1) on dimension 1 (1 and 2)
pr77351.f90:4:16:

    4 |    print *, any(shape(z) /= [4,1])  ! { dg-error "shape for elemental binary" }
      |                1
Error: Array operands are incommensurate at (1)

Final patch in preparation.
Comment 5 GCC Commits 2020-02-24 15:41:19 UTC
The master branch has been updated by Mark Eggleston <markeggleston@gcc.gnu.org>:

https://gcc.gnu.org/g:27bf39a8035445ffc71b551619d7c1a232498054

commit r10-6821-g27bf39a8035445ffc71b551619d7c1a232498054
Author: Mark Eggleston <markeggleston@gcc.gnu.org>
Date:   Mon Feb 24 15:40:03 2020 +0000

    ortran: ICE using SHAPE with FINDLOC PR93835
    
    The expression representing the array returned by SHAPE does not
    have its shape defined. An ICE occurs when FINDLOC attempts to
    use the shape of the array.  Add shape to expression before returning
    from SHAPE.
    
    Whitespace issues identified by Steven G. Kargl  <kargl@gcc.gnu.org>
    have also been fixed.
    
    gcc/fortran/ChangeLog
    
    	PR fortran/93835
    	* simplify.c (simplify_findloc_nodim) : Fix whitespace issues.
    	(gfc_simplify_shape) : Create and initialise one shape value
    	for the result expression. Set shape value with the rank of
    	the source array.
    
    gcc/testsuite/ChangeLog
    
    	PR fortran/93835
    	* gfortran.dg/pr77351.f90 : Check for one error instead of two.
    	* gfortran.dg/pr93835.f08 : New test.
Comment 6 GCC Commits 2020-02-24 15:56:00 UTC
The releases/gcc-9 branch has been updated by Mark Eggleston <markeggleston@gcc.gnu.org>:

https://gcc.gnu.org/g:ba740092516cd759ac69e89d7f502a51d8bec19a

commit r9-8271-gba740092516cd759ac69e89d7f502a51d8bec19a
Author: Mark Eggleston <markeggleston@gcc.gnu.org>
Date:   Mon Feb 24 15:53:24 2020 +0000

    fortran: ICE using SHAPE with FINDLOC PR93835
    
    	Backported from mainline
    	2020-02-24  Mark Eggleston  <markeggleston@gcc.gnu.org>
    
    	PR fortran/93835
    	* simplify.c (simplify_findloc_nodim) : Fix whitespace issues.
    	(gfc_simplify_shape) : Create and initialise one shape value
    	for the result expression. Set shape value with the rank of
    	the source array.
    
    	PR fortran/93835
    	* gfortran.dg/pr77351.f90 : Check for one error instead of two.
    	* gfortran.dg/pr93835.f08 : New test.
Comment 7 markeggleston 2020-02-26 08:19:04 UTC
committed