Bug 53298 - ICE in gfc_conv_scalarized_array_ref for ARRAY + substring
Summary: ICE in gfc_conv_scalarized_array_ref for ARRAY + substring
Status: REOPENED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: markeggleston
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks: 56818 45424
  Show dependency treegraph
 
Reported: 2012-05-09 17:11 UTC by Tobias Burnus
Modified: 2020-09-09 06:57 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-09-24 00:00:00


Attachments
ICE in gfc_conv_scalarized_array_ref (216 bytes, text/plain)
2020-07-23 08:36 UTC, Sebastien Bardeau
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2012-05-09 17:11:03 UTC
The following program segfaults. The problem is the expression
   array(:)(1:)
           ^^^--<-- substring

This combination is seemingly not handled by gfc_conv_expr_descriptor.

At the end, one gets a segfault for:
  gfc_conv_scalarized_array_ref (se=0x7fffffffcfe0, ar=0x1700538)
      at fortran/trans-array.c:3016
  3016      expr = ss->info->expr;

which is called via gfc_conv_array_ref <<< gfc_conv_variable <<< gfc_conv_string_length <<< get_array_charlen <<< gfc_conv_expr_descriptor.


  character(len=5) :: str(3)
  call f(str(:))
contains
  subroutine f(x)
   character(len=*) :: x(:)
   logical :: llll
   print *, size(x(:)(1:))
  end subroutine f
end


The program compiles flawlessly with NAG f95 and prints "3".  It fails with GCC 4.1.2, 4.3.4, 4.8.0 and probably all other versions.
Comment 1 Thomas Koenig 2013-04-06 11:46:37 UTC
Also looks like something that we could include with the array descritor reform.
Comment 2 Dominique d'Humieres 2013-04-27 13:31:04 UTC
The ICE occurs also with the fortran-dev branch (r198346 with the patch at http://gcc.gnu.org/ml/fortran/2013-04/msg00237.html).
Comment 3 Thomas Koenig 2017-11-12 17:36:22 UTC
Paul, is this something that could be fixed with the
new descriptor you introduced?
Comment 4 Harald Anlauf 2018-01-18 20:39:52 UTC
Still there at 8-trunk rev.256858, now line

3383      expr = ss->info->expr;

(gdb) print ss
$1 = (gfc_ss *) 0x0
Comment 5 Harald Anlauf 2018-03-25 21:10:46 UTC
Removing the size() in the print and the unneeded declaration of llll,
one gets a different ICE:

  character(len=5) :: str(3)
  call f(str(:))
contains
  subroutine f(x)
   character(len=*) :: x(:)
   print *,      x(:)(1:)
  end subroutine f
end

Program received signal SIGSEGV, Segmentation fault.
gfc_conv_expr (se=0xbfffe134, expr=0x0)
    at ../../trunk/gcc/fortran/trans-expr.c:7891
7891      if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->ts.f90_type == BT_VOID

(gdb) print expr
$2 = (gfc_expr *) 0x0
Comment 6 Dominique d'Humieres 2019-03-17 13:36:30 UTC
The tests in comment 0 and 5 compile if I replace '(1:)' with something such as '(1:3)'.
Comment 7 Sebastien Bardeau 2020-07-23 08:36:45 UTC
Created attachment 48919 [details]
ICE in gfc_conv_scalarized_array_ref

Example code producing an ICE in gfc_conv_scalarized_array_ref
Comment 8 Sebastien Bardeau 2020-07-23 08:38:37 UTC
I am experiencing an ICE looking pretty much the same as this one.

gfortran version and messages:

bardeau ~> gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/home/bardeau/Softs/gcc-10.1.0/libexec/gcc/x86_64-pc-linux-gnu/10.1.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../srcdir/configure --with-gmp=/home/bardeau/Softs/gcc-deps --prefix=/home/bardeau/Softs/gcc-10.1.0 --enable-languages=c,c++,fortran --disable-multilib
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.1.0 (GCC) 

bardeau ~> gfortran -c ice.f90 
ice.f90:21:0:

   21 |     t = a(1)%c(1:l).eq.b%d(1:l)
      | 
internal compiler error: Segmentation fault
0xbaf7ff crash_signal
        ../../srcdir/gcc/toplev.c:328
0x6f8c06 gfc_conv_scalarized_array_ref
        ../../srcdir/gcc/fortran/trans-array.c:3490
0x6fb19c gfc_conv_array_ref(gfc_se*, gfc_array_ref*, gfc_expr*, locus*)
        ../../srcdir/gcc/fortran/trans-array.c:3641
0x7265ae gfc_conv_variable
        ../../srcdir/gcc/fortran/trans-expr.c:2827
0x7229ee gfc_conv_expr_op
        ../../srcdir/gcc/fortran/trans-expr.c:3620
0x7229ee gfc_conv_expr(gfc_se*, gfc_expr*)
        ../../srcdir/gcc/fortran/trans-expr.c:8672
0x72aebb gfc_trans_assignment_1
        ../../srcdir/gcc/fortran/trans-expr.c:10878
0x6f2933 trans_code
        ../../srcdir/gcc/fortran/trans.c:1864
0x71bb74 gfc_generate_function_code(gfc_namespace*)
        ../../srcdir/gcc/fortran/trans-decl.c:6835
0x6f63a1 gfc_generate_module_code(gfc_namespace*)
        ../../srcdir/gcc/fortran/trans.c:2264
0x6987b5 translate_all_program_units
        ../../srcdir/gcc/fortran/parse.c:6293
0x6987b5 gfc_parse_file()
        ../../srcdir/gcc/fortran/parse.c:6545
0x6efa7f gfc_be_parse_file
        ../../srcdir/gcc/fortran/f95-lang.c:210
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
Comment 9 GCC Commits 2020-07-29 10:16:58 UTC
The master branch has been updated by Mark Eggleston <markeggleston@gcc.gnu.org>:

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

commit r11-2398-gc2e99836a2751b6d970ca6e50c1a368f5d2a2375
Author: Mark Eggleston <markeggleston@gcc.gnu.org>
Date:   Fri Jul 17 14:22:48 2020 +0100

    Fortran  : ICE in gfc_conv_scalarized_array_ref PR53298
    
    When an array of characters is an argument to a subroutine and
    is accessed using (:)(1:) an ICE occurs.  The upper bound of the
    substring does not have an expression and such should not have
    a Scalarization State structure added to the Scalarization State
    chain.
    
    2020-07-29  Mark Eggleston  <markeggleston@gcc.gnu.org>
    
    gcc/fortran/
    
            PR fortran/53298
            * trans-array.c (gfc_walk_array_ref): If ref->ss.end is set
            call gfc_get_scalar_ss.
    
    2020-07-29  Mark Eggleston  <markeggleston@gcc.gnu.org>
    
    gcc/testsuite/
    
            PR fortran/53298
            * gfortran.dg/pr53298.f90: New test.
Comment 10 markeggleston 2020-07-29 10:17:59 UTC
Committed to master.
Comment 11 Dominique d'Humieres 2020-07-29 14:32:53 UTC
The original test in comment 0 and the test in commnent 7 are giving an ICE

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x0000000100110dd9 f951`::gfc_conv_scalarized_array_ref(se=0x00007ffeefbfdfd0, ar=0x000000014560c498) at trans-array.c:3490:14
   3487	  int n;
   3488	
   3489	  ss = se->ss;
-> 3490	  expr = ss->info->expr;
   3491	  info = &ss->info->data.array;
   3492	  if (ar)
   3493	    n = se->loop->order[0];
Target 0: (f951) stopped.

because ss is NULL:

(gfc_se) $5 = {
  pre = {
    head = 0x0000000000000000
    has_scope = 0
  }
  post = {
    head = 0x0000000000000000
    has_scope = 0
  }
  expr = 0x0000000142fb3ea0
  string_length = 0x0000000000000000
  class_vptr = 0x0000000000000000
  descriptor_only = 0
  want_pointer = 0
  direct_byref = 0
  byref_noassign = 0
  ignore_optional = 0
  data_not_needed = 0
  no_function_call = 0
  force_tmp = 0
  force_no_tmp = 0
  use_offset = 0
  want_coarray = 0
  parent = 0x00007ffeefbfe7c0
  ss = 0x0000000000000000
  loop = 0x0000000000000000
}
Comment 12 markeggleston 2020-07-30 09:22:04 UTC
Fixed the ICE in comment 5.  I completely missed the "a different ICE"...

More investigation required.
Comment 13 markeggleston 2020-09-09 06:34:44 UTC
The test case in comment 0 is fixed by:

trans-array.c

@ -3638,8 +3638,11 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr,
   /* Handle scalarized references separately.  */
   if (ar->type != AR_ELEMENT)
     {
-      gfc_conv_scalarized_array_ref (se, ar);
-      gfc_advance_se_ss_chain (se);
+      if (se->ss)
+	{
+	  gfc_conv_scalarized_array_ref (se, ar);
+	  gfc_advance_se_ss_chain (se);
+	}
       return;
     }

make -j 8 check-fortran does not produce any additional test case failures on x86_64.

The test case in comment 7 still produces the same ICE.
Comment 14 markeggleston 2020-09-09 06:57:33 UTC
The test case in comment 7 proved trickier to track down.

The ICE occurs in this code:

  /* Components can correspond to fields of different containing
     types, as components are created without context, whereas
     a concrete use of a component has the type of decl as context.
     So, if the type doesn't match, we search the corresponding
     FIELD_DECL in the parent type.  To not waste too much time
     we cache this result in norestrict_decl.
     On the other hand, if the context is a UNION or a MAP (a
     RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL.  */

  if (context != TREE_TYPE (decl)
      && !(   TREE_CODE (TREE_TYPE (field)) == UNION_TYPE /* Field is union */
          || TREE_CODE (context) == UNION_TYPE)) /* Field is map */
    {
      tree f2 = c->norestrict_decl;
      if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
==>	for (f2 = TYPE_FIELDS (TREE_TYPE (decl)); f2; f2 = DECL_CHAIN (f2))
	  if (TREE_CODE (f2) == FIELD_DECL
	      && DECL_NAME (f2) == DECL_NAME (field))
	    break;
      gcc_assert (f2);
      c->norestrict_decl = f2;
      field = f2;
    }


The ICE occurs at the line marked with ==>, the assignment f2 = TYPE_FIELDS (TREE_TYPE (decl)) hides a call to a routine that returns a null pointer which is then used causing the ICE.

I speculated that the code dealing with f2 should not have been executed. I noted that in the comments "On the other hand, if the context is a UNION or a MAP (a RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL."  This does not match the code that follows.

The following change:

trans-expr.c

@@ -2474,8 +2474,8 @@ gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
      RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL.  */
 
   if (context != TREE_TYPE (decl)
-      && !(   TREE_CODE (TREE_TYPE (field)) == UNION_TYPE /* Field is union */
-           || TREE_CODE (context) == UNION_TYPE))         /* Field is map */
+      && (   TREE_CODE (context) == UNION_TYPE /* Field is union */
+          || TREE_CODE (context) == MAP_TYPE)) /* Field is map */
     {
       tree f2 = c->norestrict_decl;
       if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))

matches the comment and also fixes the ICE for the test case in comment 7.

make -j 8 check-fortran was looking good until test case failures were reported for:

gfortran.dg/finalize_35.f90
gfortran.dg/finalize_36.f90