Bug 38538 - ICE with elemental character function
ICE with elemental character function
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: fortran
4.4.0
: P3 normal
: ---
Assigned To: Paul Thomas
: ice-on-valid-code
Depends on:
Blocks: 19276 32834
  Show dependency treegraph
 
Reported: 2008-12-16 04:11 UTC by Vivek Rao
Modified: 2009-04-06 10:52 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-12-18 09:13:47


Attachments
Provisional patch for the PR (5.19 KB, patch)
2008-12-18 16:35 UTC, Paul Thomas
Details | Diff
testcase for the PR (963 bytes, application/octet-stream)
2008-12-18 16:38 UTC, Paul Thomas
Details
a not quite patch for the PR (6.98 KB, patch)
2008-12-19 23:59 UTC, Paul Thomas
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Vivek Rao 2008-12-16 04:11:22 UTC
For the code below stored in xtemp.f90

module abc
implicit none
contains
subroutine xmain()
call foo(func("_"//bar()))
end subroutine xmain
!
function bar() result(yy)
character (len=1) :: yy(1)
yy = ""
end function bar
!
elemental function func(yy) result(xy)
character (len=*), intent(in) :: yy
character (len=len(yy)) :: xy
xy = yy
end function func
!
subroutine foo(cc)
character (len=*), intent(in) :: cc(:)
print*,cc
end subroutine foo
end module abc

gfortran -c xtemp.f90 gives

xtemp.f90: In function 'xmain':
xtemp.f90:8: internal compiler error: in gfc_conv_function_call, at fortran/trans-expr.c:2846
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

gfortran -v gives

Built by Equation Solution (http://www.Equation.com).
Using built-in specs.
Target: i386-pc-mingw32
Configured with: ../gcc-4.4-20081212-mingw/configure --host=i386-pc-mingw32 --build=x86_64-unknown-linux-gnu --target=i386-pc-mingw32 --prefix=/home/gfortran/gcc-home/binary/mingw32/native/x86_32/gcc/4.4-20081212 --with-gcc --with-gnu-ld --with-gnu-as --disable-shared --disable-nls --disable-tls --with-gmp=/home/gfortran/gcc-home/binary/mingw32/native/x86_32/gmp --with-mpfr=/home/gfortran/gcc-home/binary/mingw32/native/x86_32/mpfr --enable-languages=c,fortran,c++ --with-sysroot=/home/gfortran/gcc-home/binary/mingw32/cross/x86_32/gcc/4.4-20081212 --enable-libgomp --enable-threads=win32 --disable-win32-registry
Thread model: win32
gcc version 4.4.0 20081212 (experimental) (GCC)
Comment 1 Dominique d'Humieres 2008-12-16 07:24:31 UTC
Confirmed on (powerpc|i686)-apple-darwin9 revision 142767.

Comment 2 Mikael Morin 2008-12-16 15:35:45 UTC
Yes, confirmed. 

The offending line is:
call foo(func("_"//bar()))

In trans-expr.c, se->loop is NULL in the gcc_assert:
2844       else if (sym->result->attr.dimension)
2845         {
2846           gcc_assert (se->loop && info);
2847 
2848           /* Set the type of the array.  */
2849           tmp = gfc_typenode_for_spec (&ts);
2850           info->dimen = se->loop->dimen;
2851 

backtrace:
(gdb) bt
#0  fancy_abort (file=0xbe0240 "../../src/gcc/fortran/trans-expr.c", 
    line=2846, function=0xbe0b40 "gfc_conv_function_call")
    at ../../src/gcc/diagnostic.c:711
#1  0x00000000004b2e0a in gfc_conv_function_call (se=0x7fff89088320, 
    sym=0x2738da0, arg=<value optimized out>, 
    append_args=<value optimized out>)
    at ../../src/gcc/fortran/trans-expr.c:2846
#2  0x00000000004b367b in gfc_conv_function_expr (se=0x7fff89088320, 
    expr=<value optimized out>) at ../../src/gcc/fortran/trans-expr.c:3345
#3  0x00000000004b61d4 in gfc_conv_expr_op (se=0x7fff890884a0, expr=0x27426e0)
    at ../../src/gcc/fortran/trans-expr.c:1147
#4  0x00000000004b7943 in gfc_conv_string_length (cl=0x2740dd0, 
    expr=<value optimized out>, pblock=0x7fff89088870)
    at ../../src/gcc/fortran/trans-expr.c:328
#5  0x000000000049cd14 in gfc_conv_expr_descriptor (se=<value optimized out>, 
    expr=<value optimized out>, ss=0x2742380)
    at ../../src/gcc/fortran/trans-array.c:4929
#6  0x00000000004bd987 in gfc_conv_intrinsic_len (se=0x7fff89088d90, 
    expr=<value optimized out>) at ../../src/gcc/fortran/trans-intrinsic.c:2906
#7  0x00000000004c01d4 in gfc_conv_intrinsic_function (se=0x7fff89088d90, 
    expr=0x2741c70) at ../../src/gcc/fortran/trans-intrinsic.c:4682
#8  0x00000000004b3633 in gfc_conv_function_expr (se=0x7fff89088d90, 
    expr=0xb1e) at ../../src/gcc/fortran/trans-expr.c:3328
#9  0x00000000004b76ea in gfc_apply_interface_mapping (mapping=0x7fff89088e30, 
    se=0x7fff89088d90, expr=0x2741c70)
    at ../../src/gcc/fortran/trans-expr.c:2145
#10 0x000000000049d5bf in gfc_conv_expr_descriptor (se=<value optimized out>, 
    expr=<value optimized out>, ss=0x27416b0)
    at ../../src/gcc/fortran/trans-array.c:4721
#11 0x00000000004a06a3 in gfc_conv_array_parameter (se=0x7fff89089030, 
    expr=0x2702b90, ss=0x27416b0, g77=<value optimized out>, fsym=0x273add0, 
    proc_name=0x7fff89087bb0 "") at ../../src/gcc/fortran/trans-array.c:5277
#12 0x00000000004b22d4 in gfc_conv_function_call (se=0x7fff890895f0, 
    sym=0x273ab60, arg=0x26b27b0, append_args=<value optimized out>)
    at ../../src/gcc/fortran/trans-expr.c:2691
#13 0x00000000004cf8df in gfc_trans_call (code=<value optimized out>, 
    dependency_check=0 '\0') at ../../src/gcc/fortran/trans-stmt.c:356
#14 0x00000000004943c5 in gfc_trans_code (code=0x2738340)
    at ../../src/gcc/fortran/trans.c:1117
#15 0x00000000004abe6d in gfc_generate_function_code (ns=0x2737200)
    at ../../src/gcc/fortran/trans-decl.c:3843
#16 0x0000000000493a33 in gfc_generate_module_code (ns=<value optimized out>)
    at ../../src/gcc/fortran/trans.c:1319
#17 0x0000000000461624 in gfc_parse_file ()
    at ../../src/gcc/fortran/parse.c:3855
#18 0x0000000000490c9d in gfc_be_parse_file (set_yydebug=<value optimized out>)
    at ../../src/gcc/fortran/f95-lang.c:236
#19 0x000000000074545d in toplev_main (argc=<value optimized out>, 
    argv=<value optimized out>) at ../../src/gcc/toplev.c:970
#20 0x00007f6a80694526 in __libc_start_main () from /lib/libc.so.6
#21 0x0000000000405d19 in _start ()
Comment 3 Dominique d'Humieres 2008-12-16 16:03:09 UTC
If the subroutine

subroutine xmain()
call foo(func("_"//bar()))
end subroutine xmain

is replaced with

subroutine xmain()
character (len=2) :: zz(2)
zz=func("_"//bar())
call foo(zz)
end subroutine xmain

the code compiles and seems to give a sensible executable.

Comment 4 Thomas Koenig 2008-12-17 07:33:37 UTC
Not a regression:

 gfortran ice.f90
ice.f90: In function 'xmain':
ice.f90:8: internal compiler error: in gfc_conv_function_call, at fortran/trans-expr.c:2846
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
$ gfortran-4.3 ice.f90
ice.f90: In function 'xmain':
ice.f90:8: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.3/README.Bugs> for instructions.
$ gfortran-4.2 ice.f90
ice.f90: In function 'xmain':
ice.f90:5: internal compiler error: in expand_expr_real_1, at expr.c:6956
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
For Debian GNU/Linux specific bug reporting instructions,
see <URL:file:///usr/share/doc/gcc-4.2/README.Bugs>.
Comment 5 Paul Thomas 2008-12-18 09:13:47 UTC
I am most of the way onto a solution for this so I'll assign myself.

The source of the problem is highlighted by two tests:

s/call foo(func("_"//bar()))/call foo(func(bar()))/

works fine as does a modified testcase with integers instead of characters and the concatenation replaced by another operation such as 1 + bar().

Thus the likely problem is the string length.  This is confirmed by setting it to gfc_index_one_node in gfc_conv_expr_descriptor, whereupon the compilation completes because it is now possible to calculate a (wrong!) size for the temporary.

An elemental function argument works because this is explicitly taken care of by get_elemental_fcn_charlen. When I wrote this function, I noted that this PR was a possibility but could not see an easy way to deal with it.  The time has come to do the difficult thing! We'll have to scan the expression and sum the string lengths, calling get_elemental_fcn_charlen as necessary.  It is a happy chance that there is only the concatenation operator:-)

It is increasingly my opinion that interface mapping should be done in resolution, at the end of resolve_call and resolve_function, but that will have to wait for gcc-4.6.

Paul

Cheers

Paul
Comment 6 Paul Thomas 2008-12-18 16:35:26 UTC
Created attachment 16928 [details]
Provisional patch for the PR

Testcase follows in next attachement.
Comment 7 Paul Thomas 2008-12-18 16:38:02 UTC
Created attachment 16929 [details]
testcase for the PR

This might have departed somewhat from the original but it does at least work with the patch!

Note that the patch is not regtested.

Paul
Comment 8 Dominique d'Humieres 2008-12-18 21:20:10 UTC
With the patch in comment #6, this pr is fixed but now the code

  character(len=1) :: string
  print *, transfer(((transfer(string,"x",1))), "x")
  end

and friends (from pr31608) gives a bus error:

pr31608_1.f90: In function 'MAIN__':
pr31608_1.f90:1: internal compiler error: Bus error
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

Note also that I have been unable to read the test in comment #7.
Comment 9 Dominique d'Humieres 2008-12-18 21:36:57 UTC
Another bus error with

! { dg-do run }
! Test fix of PR28118, in which a substring reference to an
! actual argument with an array reference would cause a segfault.
!
! Contributed by Paul Thomas  <pault@gcc.gnu.org>
!
program gfcbug33
  character(12) :: a(2)
  a(1) = "abcdefghijkl"
  a(2) = "mnopqrstuvwx"
  call foo ((a(2:1:-1)(6:)))
  call bar ((a(:)(7:11)))
contains
  subroutine foo (chr)
    character(7) :: chr(:)
    if (chr(1)//chr(2) .ne. "rstuvwxfghijkl") call abort ()
  end subroutine foo
  subroutine bar (chr)
    character(*) :: chr(:)
    if (trim(chr(1))//trim(chr(2)) .ne. "ghijkstuvw") call abort ()
  end subroutine bar
end program gfcbug33

pr28118.f90: In function 'gfcbug33':
pr28118.f90:10: internal compiler error: Bus error
Comment 10 Paul Thomas 2008-12-19 08:07:53 UTC
Many thanks, Dominique! At least I have something to work on. It's a cursed nuisance not having access to a fully functioning system, when I have time to work on gfortran. I think that I shall have to take up Tobi's offer of remote access to his machine.

Meilleurs voeux et bonnes fetes!

Paul
Comment 11 Thomas Koenig 2008-12-19 17:20:36 UTC
(In reply to comment #10)
> Many thanks, Dominique! At least I have something to work on. It's a cursed
> nuisance not having access to a fully functioning system, when I have time to
> work on gfortran. I think that I shall have to take up Tobi's offer of remote
> access to his machine.
> 

Hi Paul,

you could apply for an account on the gcc compile farm (I have).  As
long as you have putty, and your private key, you can log on from
just about everywhere.

Very useful, and they have a couple of really fast systems, too!
Comment 12 Paul Thomas 2008-12-19 23:59:10 UTC
Created attachment 16949 [details]
a not quite patch for the PR

I'm down to one regression now - the last test of char_length_7.f90.

Pah! That was tough in the first place....

Cheers

Paul
Comment 13 Dominique d'Humieres 2008-12-20 13:01:38 UTC
The patch in comment #12 fixes the pr without causing the regressions reported in comments #8 and #9.
Compiling gcc/testsuite/gfortran.dg/char_length_7.f90 gives an ICE:

gimplification failed:
2 <integer_cst 0x4168ec30 type <integer_type 0x41611310 integer(kind=4)> constant 2>
/opt/gcc/_gcc_clean/gcc/testsuite/gfortran.dg/char_length_7.f90: In function 'xx':
/opt/gcc/_gcc_clean/gcc/testsuite/gfortran.dg/char_length_7.f90:30: internal compiler error: gimplification failed

and the following code:

[ibook-dhum] f90/bug% cat pr31608_4_red_1.f90
  character(len=1)  :: string = "z"
  character(len=20) :: tmp = ""
  tmp = Upper ("abcdefgh")
  print *, tmp
 contains
  Character (len=20) Function Upper (string)
    Character(len=*) string
    print *, len(string)
    print *, size(transfer(string,"xy",len(string)))
    Upper = ""
    Upper(1:2) =                                                                &
     transfer(merge(transfer(string,"xy",len(string)),    &
       string(1:2), .true.), "xy")
    return
  end function Upper
end

yields a wrong code: the executable gives

           8
           4
 ab                  

while it gives

           8
           8
 ab                  

when compiled with ifort.

Currently regtesting.
Comment 14 Dominique d'Humieres 2008-12-20 14:27:41 UTC
Regtested with -m32 and -m64 without other regression that gcc/testsuite/gfortran.dg/char_length_7.f90. The offending line is:

! This was another bug, uncovered when the PR was fixed.
  if (any(ccopy(z//mz(:)(i:j)) .ne. (/"zzgh ","zzjk "/))) call abort ()

while

  if (any(ccopy(z//mz(:)(2:3)) .ne. (/"zzgh ","zzjk "/))) call abort ()

is compiled without problem.
Comment 15 Paul Thomas 2008-12-24 17:08:44 UTC
(In reply to comment #13)
Dear Dominique,

>     print *, len(string)
>     print *, size(transfer(string,"xy",len(string)))

> yields a wrong code: the executable gives
> 
>            8
>            4
>  ab                  
> 
> while it gives
> 
>            8
>            8
>  ab                  
> 
> when compiled with ifort.

This is an underlying bug that precedes the patch.  We'd better have a PR for it!

Cheers

Paul
Comment 16 Paul Thomas 2009-03-13 12:52:57 UTC
Patch pending. See:

http://gcc.gnu.org/ml/fortran/2009-03/msg00050.html

Paul
Comment 17 Paul Thomas 2009-03-31 18:42:49 UTC
This was fixed on trunk as revision 145196 but I screwed up the commit message.

Paul

Comment 18 Paul Thomas 2009-04-06 10:52:53 UTC
Fixed on trunk.  I am prepared to backport but the mood appears to be against it.

Thanks for the report.

Paul