Bug 60593 - ICE with deferred length variable in FORALL
Summary: ICE with deferred length variable in FORALL
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: ---
Assignee: Paul Thomas
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-03-19 17:32 UTC by kargls
Modified: 2016-03-09 20:55 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.9.0
Last reconfirmed: 2014-03-19 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description kargls 2014-03-19 17:32:19 UTC

    
Comment 1 kargls 2014-03-19 17:37:57 UTC
% gfc4x -c -Wall h.f90
h.f90: In function 'c2fchar':
h.f90:29:0: internal compiler error: Segmentation fault
       forall (i = 1:c_str_len) res(i:i) = string_p(i)
 ^
no stack trace because unwind library not available
Please submit a full bug report,
with preprocessed source if appropriate.

% cat h.f90

module stringhelper_m

  implicit none

  type :: string_t
     character(:), allocatable :: string
  end type

  interface len
     function strlen(s) bind(c,name='strlen')
       use iso_c_binding
       implicit none
       type(c_ptr), intent(in), value :: s
       integer(c_size_t) :: strlen
     end function
  end interface

  contains

    function C2FChar(c_charptr) result(res)
      use iso_c_binding
      type(c_ptr), intent(in) :: c_charptr
      character(:), allocatable :: res
      character(kind=c_char,len=1), pointer :: string_p(:)
      integer i, c_str_len
      c_str_len = int(len(c_charptr))
      call c_f_pointer(c_charptr, string_p, [c_str_len])
      allocate(character(c_str_len) :: res)
      forall (i = 1:c_str_len) res(i:i) = string_p(i)
    end function

end module

(gdb) run h.f90
Starting program: /home/sgk/work/4x/libexec/gcc/x86_64-unknown-freebsd11.0/4.9.0/f951 h.f90
 c2fchar
Program received signal SIGSEGV, Segmentation fault.
0x00000000007abaf4 in contains_struct_check (__s=<optimized out>, 
    __f=<optimized out>, __l=<optimized out>, __g=<optimized out>, 
    __t=<optimized out>, __s=<optimized out>, __f=<optimized out>, 
    __l=<optimized out>, __g=<optimized out>) at ../../gcc4x/gcc/tree.h:2822
2822      if (tree_contains_struct[TREE_CODE (__t)][__s] != 1)
(gdb) bt
#0  0x00000000007abaf4 in contains_struct_check (__s=<optimized out>, 
    __f=<optimized out>, __l=<optimized out>, __g=<optimized out>, 
    __t=<optimized out>, __s=<optimized out>, __f=<optimized out>, 
    __l=<optimized out>, __g=<optimized out>) at ../../gcc4x/gcc/tree.h:2822
#1  fold_convert_loc (loc=0, type=0x202c2d7e0, arg=0x0)
    at ../../gcc4x/gcc/fold-const.c:1956
#2  0x00000000006501f3 in allocate_temp_for_forall_nest_1 (type=0x202d6a930, 
    size=0x202d77130, block=0x7fffffffce40, ptemp1=0x7fffffffca50)
    at ../../gcc4x/gcc/fortran/trans-stmt.c:3288
#3  0x0000000000650949 in allocate_temp_for_forall_nest (
    nested_forall_info=<optimized out>, type=<optimized out>, 
    inner_size=<optimized out>, inner_size_body=<optimized out>, 
    block=<optimized out>, ptemp1=<optimized out>, 
    nested_forall_info=<optimized out>, type=<optimized out>, 
    inner_size=<optimized out>, inner_size_body=<optimized out>, 
    block=<optimized out>, ptemp1=<optimized out>)
    at ../../gcc4x/gcc/fortran/trans-stmt.c:3319
#4  gfc_trans_assign_need_temp (expr1=0x2034ac300, expr2=0x2034ac540, 
    wheremask=0x0, invert=false, nested_forall_info=0x2034d13c0, 
    block=0x7fffffffce40) at ../../gcc4x/gcc/fortran/trans-stmt.c:3408
#5  0x000000000064ccb2 in gfc_trans_forall_1 (code=0x2034ac840, 
    nested_forall_info=<optimized out>)
    at ../../gcc4x/gcc/fortran/trans-stmt.c:3886
#6  0x00000000005eb15e in trans_code (code=<optimized out>, cond=0x0)
    at ../../gcc4x/gcc/fortran/trans.c:1786
#7  0x00000000006127cc in gfc_generate_function_code (ns=0x20344b400)
    at ../../gcc4x/gcc/fortran/trans-decl.c:5610
#8  0x00000000005eb5ae in gfc_generate_module_code (ns=<optimized out>)
    at ../../gcc4x/gcc/fortran/trans.c:1972
#9  0x000000000058eb95 in translate_all_program_units (
    gfc_global_ns_list=<optimized out>, main_in_tu=<optimized out>)
    at ../../gcc4x/gcc/fortran/parse.c:4523
#10 gfc_parse_file () at ../../gcc4x/gcc/fortran/parse.c:4733
#11 0x00000000005d72ea in gfc_be_parse_file ()
    at ../../gcc4x/gcc/fortran/f95-lang.c:188
#12 0x0000000000a0978a in compile_file () at ../../gcc4x/gcc/toplev.c:548
#13 0x0000000000a0958b in do_compile () at ../../gcc4x/gcc/toplev.c:1914
#14 toplev_main (argc=2, argv=0x7fffffffd4d8) at ../../gcc4x/gcc/toplev.c:1990
#15 0x00000000005134af in _start ()
Comment 2 Steve Kargl 2014-03-19 17:50:45 UTC
Here's a reduced testcase that appears to lead to
the same ICE without the ISO C binding detour.

function C2FChar(j, s) result(res)
   implicit none
   integer, intent(in) :: j
   character(len=:), pointer, intent(in) :: s
   character(len=:), allocatable :: res
   character(len=1), pointer :: sp
   integer i
   sp => s
   allocate(character(j) :: res)
   forall (i = 1:j) res(i:i) = sp(i:i)
end function
Comment 3 Dominique d'Humieres 2014-03-19 18:01:14 UTC
It looks similar to the ICE reported in pr51976 comment 8, although the ICEs are different.
Comment 4 Steve Kargl 2014-03-19 18:10:07 UTC
On Wed, Mar 19, 2014 at 06:01:14PM +0000, dominiq at lps dot ens.fr wrote:
> 
> --- Comment #3 from Dominique d'Humieres <dominiq at lps dot ens.fr> ---
> It looks similar to the ICE reported in pr51976 comment 8, although the ICEs
> are different.
> 

It does look similar.  Perhaps, janus patch has simply moved
the issue to a new location.  

A farther reduced test case without the pointer assignment.

function C2FChar(j, s) result(res)
   implicit none
   integer, intent(in) :: j
   character(len=:), pointer, intent(in) :: s
   character(len=:), allocatable :: res
   integer i
   allocate(character(j) :: res)
   forall (i = 1:j) res(i:i) = s(i:i)
end function
Comment 5 Dominique d'Humieres 2014-08-29 09:45:27 UTC
This PR is fixed by the patch at https://gcc.gnu.org/ml/fortran/2014-08/msg00114.html. Test that can be executed:

character(len=10), target :: c
character(len=:), pointer :: p

c = 'abcdefghij'
p => c(2:10)
print *, C2FChar(5, p)

contains
function C2FChar(j, s) result(res)
   implicit none
   integer, intent(in) :: j
   character(len=:), pointer, intent(in) :: s
   character(len=:), allocatable :: res
   integer i
   allocate(character(j) :: res)
   forall (i = 1:j) res(i:i) = s(i:i)
end function
end

[Book15] f90/bug% a.out
 bcdef
Comment 6 Tobias Burnus 2014-08-30 18:47:36 UTC
Author: burnus
Date: Sat Aug 30 18:47:04 2014
New Revision: 214757

URL: https://gcc.gnu.org/viewcvs?rev=214757&root=gcc&view=rev
Log:
2014-08-30  Tobias Burnus  <burnus@net-b.de>

        PR fortran/62278
        PR fortran/44735
        PR fortran/60593
        * dependency.c (gfc_check_dependency): Allow for optimizations
        in the pointer-alias check.


Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/dependency.c
Comment 7 Paul Thomas 2016-01-15 20:34:31 UTC
Author: pault
Date: Fri Jan 15 20:33:58 2016
New Revision: 232450

URL: https://gcc.gnu.org/viewcvs?rev=232450&root=gcc&view=rev
Log:
2016-01-15  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/64324
	* resolve.c (check_uop_procedure): Prevent deferred length
	characters from being trapped by assumed length error.

	PR fortran/49630
	PR fortran/54070
	PR fortran/60593
	PR fortran/60795
	PR fortran/61147
	PR fortran/64324
	* trans-array.c (gfc_conv_scalarized_array_ref): Pass decl for
	function as well as variable expressions.
	(gfc_array_init_size): Add 'expr' as an argument. Use this to
	correctly set the descriptor dtype for deferred characters.
	(gfc_array_allocate): Add 'expr' to the call to
	'gfc_array_init_size'.
	* trans.c (gfc_build_array_ref): Expand logic for setting span
	to include indirect references to character lengths.
	* trans-decl.c (gfc_get_symbol_decl): Ensure that deferred
	result char lengths that are PARM_DECLs are indirectly
	referenced both for directly passed and by reference.
	(create_function_arglist): If the length type is a pointer type
	then store the length as the 'passed_length' and make the char
	length an indirect reference to it.
	(gfc_trans_deferred_vars): If a character length has escaped
	being set as an indirect reference, return it via the 'passed
	length'.
	* trans-expr.c (gfc_conv_procedure_call): The length of
	deferred character length results is set TREE_STATIC and set to
	zero.
	(gfc_trans_assignment_1): Do not fix the rse string_length if
	it is a variable, a parameter or an indirect reference. Add the
	code to trap assignment of scalars to unallocated arrays.
	* trans-stmt.c (gfc_trans_allocate): Remove 'def_str_len' and
	all references to it. Instead, replicate the code to obtain a
	explicitly defined string length and provide a value before
	array allocation so that the dtype is correctly set.
	trans-types.c (gfc_get_character_type): If the character length
	is a pointer, use the indirect reference.

2016-01-15  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/49630
	* gfortran.dg/deferred_character_13.f90: New test for the fix
	of comment 3 of the PR.

	PR fortran/54070
	* gfortran.dg/deferred_character_8.f90: New test
	* gfortran.dg/allocate_error_5.f90: New test

	PR fortran/60593
	* gfortran.dg/deferred_character_10.f90: New test

	PR fortran/60795
	* gfortran.dg/deferred_character_14.f90: New test

	PR fortran/61147
	* gfortran.dg/deferred_character_11.f90: New test

	PR fortran/64324
	* gfortran.dg/deferred_character_9.f90: New test

Added:
    trunk/gcc/testsuite/gfortran.dg/allocate_error_5.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_10.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_11.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_12.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_13.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_14.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_8.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_9.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-decl.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-stmt.c
    trunk/gcc/fortran/trans-types.c
    trunk/gcc/fortran/trans.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 Paul Thomas 2016-01-16 09:56:55 UTC
Fixed on trunk. I will wait a few weeks before fixing on 5-branch.

Paul
Comment 9 Paul Thomas 2016-03-09 20:50:31 UTC
Author: pault
Date: Wed Mar  9 20:49:58 2016
New Revision: 234093

URL: https://gcc.gnu.org/viewcvs?rev=234093&root=gcc&view=rev
Log:
2016-03-09  Paul Thomas  <pault@gcc.gnu.org>

	Backport from trunk.
	PR fortran/69423
	* trans-decl.c (create_function_arglist): Deferred character
	length functions, with and without declared results, address
	the passed reference type as '.result' and the local string
	length as '..result'.
	(gfc_null_and_pass_deferred_len): Helper function to null and
	return deferred string lengths, as needed.
	(gfc_trans_deferred_vars): Call it, thereby reducing repeated
	code, add call for deferred arrays and reroute pointer function
	results. Avoid using 'tmp' for anything other that a temporary
	tree by introducing 'type_of_array' for the arrayspec type.

2016-03-09  Paul Thomas  <pault@gcc.gnu.org>

	Backport from trunk.
	PR fortran/64324
	* resolve.c (check_uop_procedure): Prevent deferred length
	characters from being trapped by assumed length error.

	Backport from trunk.
	PR fortran/49630
	PR fortran/54070
	PR fortran/60593
	PR fortran/60795
	PR fortran/61147
	PR fortran/64324
	* trans-array.c (gfc_conv_scalarized_array_ref): Pass decl for
	function as well as variable expressions.
	(gfc_array_init_size): Add 'expr' as an argument. Use this to
	correctly set the descriptor dtype for deferred characters.
	(gfc_array_allocate): Add 'expr' to the call to
	'gfc_array_init_size'.
	* trans.c (gfc_build_array_ref): Expand logic for setting span
	to include indirect references to character lengths.
	* trans-decl.c (gfc_get_symbol_decl): Ensure that deferred
	result char lengths that are PARM_DECLs are indirectly
	referenced both for directly passed and by reference.
	(create_function_arglist): If the length type is a pointer type
	then store the length as the 'passed_length' and make the char
	length an indirect reference to it.
	(gfc_trans_deferred_vars): If a character length has escaped
	being set as an indirect reference, return it via the 'passed
	length'.
	* trans-expr.c (gfc_conv_procedure_call): The length of
	deferred character length results is set TREE_STATIC and set to
	zero.
	(gfc_trans_assignment_1): Do not fix the rse string_length if
	it is a variable, a parameter or an indirect reference. Add the
	code to trap assignment of scalars to unallocated arrays.
	* trans-stmt.c (gfc_trans_allocate): Remove 'def_str_len' and
	all references to it. Instead, replicate the code to obtain a
	explicitly defined string length and provide a value before
	array allocation so that the dtype is correctly set.
	trans-types.c (gfc_get_character_type): If the character length
	is a pointer, use the indirect reference.

2016-03-09  Paul Thomas  <pault@gcc.gnu.org>

	Backport from trunk.
	PR fortran/69423
	* gfortran.dg/deferred_character_15.f90 : New test.

2016-03-09  Paul Thomas  <pault@gcc.gnu.org>

	Backport from trunk.
	PR fortran/49630
	* gfortran.dg/deferred_character_13.f90: New test for the fix
	of comment 3 of the PR.

	Backport from trunk.
	PR fortran/54070
	* gfortran.dg/deferred_character_8.f90: New test
	* gfortran.dg/allocate_error_5.f90: New test

	Backport from trunk.
	PR fortran/60593
	* gfortran.dg/deferred_character_10.f90: New test

	Backport from trunk.
	PR fortran/60795
	* gfortran.dg/deferred_character_14.f90: New test

	Backport from trunk.
	PR fortran/61147
	* gfortran.dg/deferred_character_11.f90: New test

	Backport from trunk.
	PR fortran/64324
	* gfortran.dg/deferred_character_9.f90: New test


Added:
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/allocate_error_5.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_10.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_11.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_12.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_13.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_14.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_15.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_8.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_9.f90
Modified:
    branches/gcc-5-branch/gcc/fortran/ChangeLog
    branches/gcc-5-branch/gcc/fortran/resolve.c
    branches/gcc-5-branch/gcc/fortran/trans-array.c
    branches/gcc-5-branch/gcc/fortran/trans-decl.c
    branches/gcc-5-branch/gcc/fortran/trans-expr.c
    branches/gcc-5-branch/gcc/fortran/trans-stmt.c
    branches/gcc-5-branch/gcc/fortran/trans-types.c
    branches/gcc-5-branch/gcc/fortran/trans.c
    branches/gcc-5-branch/gcc/testsuite/ChangeLog
Comment 10 Paul Thomas 2016-03-09 20:55:32 UTC
Fixed on trunk and 5-branch.

Thanks for the report.

Paul