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.
Also looks like something that we could include with the array descritor reform.
The ICE occurs also with the fortran-dev branch (r198346 with the patch at http://gcc.gnu.org/ml/fortran/2013-04/msg00237.html).
Paul, is this something that could be fixed with the new descriptor you introduced?
Still there at 8-trunk rev.256858, now line 3383 expr = ss->info->expr; (gdb) print ss $1 = (gfc_ss *) 0x0
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
The tests in comment 0 and 5 compile if I replace '(1:)' with something such as '(1:3)'.
Created attachment 48919 [details] ICE in gfc_conv_scalarized_array_ref Example code producing an ICE in gfc_conv_scalarized_array_ref
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.
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.
Committed to master.
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 }
Fixed the ICE in comment 5. I completely missed the "a different ICE"... More investigation required.
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.
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