Bug 31427

Summary: TRANSFER with mold kind /= lval kind: ICE on ia64, i686; no warning
Product: gcc Reporter: Michael Richmond <michael.a.richmond>
Component: fortranAssignee: Brooks Moses <brooks>
Status: RESOLVED FIXED    
Severity: normal CC: burnus, dfranke, gcc-bugs
Priority: P3 Keywords: diagnostic, ice-on-valid-code, wrong-code
Version: 4.3.0   
Target Milestone: 4.3.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2007-04-06 23:11:11
Bug Depends on:    
Bug Blocks: 31237    

Description Michael Richmond 2007-04-02 18:47:09 UTC
When I compile the following program I get the message "GNU MP: Cannot reallocate memory"

PROGRAM test
INTEGER(KIND=1) :: i(1)
i = (/ TRANSFER("a", 0) /)
END PROGRAM test
Comment 1 kargls 2007-04-02 19:06:22 UTC
*** Bug 31428 has been marked as a duplicate of this bug. ***
Comment 2 Daniel Franke 2007-04-02 20:10:26 UTC
Can confirm a crash in f951. Since there were quite a lot of TRANSFER related reports lately, I can not tell if this a new one.

Backtrace:
Starting program: /home/daniel/i686-pc-linux-gnu/gcc/libexec/gcc/i686-pc-linux-gnu/4.3.0/f951 -g -Wall 31427.f90

Program received signal SIGSEGV, Segmentation fault.
0xb7f36571 in __gmpn_copyi () from /usr/lib/libgmp.so.3
(gdb) bt
#0  0xb7f36571 in __gmpn_copyi () from /usr/lib/libgmp.so.3
#1  0xb7f238b4 in __gmpz_set () from /usr/lib/libgmp.so.3
#2  0x0804d9d6 in gfc_int2int (src=0x8894930, kind=1)
    at ../../../gcc/gcc/fortran/arith.c:2006
#3  0x0809b1dd in gfc_convert_constant (e=0x8894758, type=BT_INTEGER, kind=1)
    at ../../../gcc/gcc/fortran/simplify.c:4035
#4  0x08068134 in do_simplify (specific=0x888a3f8, e=0x8894898)
    at ../../../gcc/gcc/fortran/intrinsic.c:3112
#5  0x08068305 in gfc_convert_type_warn (expr=0x8894898, ts=0x88945ac,
    eflag=1, wflag=1) at ../../../gcc/gcc/fortran/intrinsic.c:3579
#6  0x08068578 in gfc_convert_type (expr=0x8894898, ts=0x88945ac, eflag=1)
    at ../../../gcc/gcc/fortran/intrinsic.c:3491
#7  0x0809633f in resolve_code (code=<value optimized out>, ns=0x885a1e8)
    at ../../../gcc/gcc/fortran/resolve.c:5163
#8  0x08097a24 in gfc_resolve (ns=0x885a1e8)
    at ../../../gcc/gcc/fortran/resolve.c:7343
#9  0x0808c0ca in gfc_parse_file () at ../../../gcc/gcc/fortran/parse.c:3245
#10 0x080ab660 in gfc_be_parse_file (set_yydebug=0)
    at ../../../gcc/gcc/fortran/f95-lang.c:305
#11 0x0830042d in toplev_main (argc=4, argv=0xbfd587f4)
    at ../../../gcc/gcc/toplev.c:1050
#12 0x080ed162 in main (argc=49, argv=0xa0000000) at ../../../gcc/gcc/main.c:35
Comment 3 Tobias Burnus 2007-04-02 23:10:16 UTC
Hmm, I cannot reproduce this on x86_64-unknown-linux-gnu/openSUSE 10.2 with either gcc 4.2 (vanilla) nor with gcc 4.3 (current SVN, very mildly patched) and with neither -m32 nor -m64 running under valgrind. (This is with gmp 4.2.1.)
Comment 4 Daniel Franke 2007-04-03 09:34:02 UTC
Neither can I (gcc-4.2, gcc-svn). x86_64 seems to be immune. Another i686 machine again crashes  (gcc-4.2, gcc-svn), so does an ia64 (gcc-4.2). All boxes have gmp-4.2.1 installed.
Comment 5 Daniel Franke 2007-04-03 09:37:25 UTC
For i686/SuSE 10.1 valgrind-3.2.2 gives:

==13209== Warning: set address range perms: large range 568154688 (undefined)
==13209== Invalid read of size 4
==13209==    at 0x40849CD: __gmpn_copyi (in /h/franke/packages/i686-pc-linux-gnu/gmp-4.2.1/lib/libgmp.so.3.4.1)
==13209==  Address 0x42051E4 is 0 bytes after a block of size 67,524 alloc'd
==13209==    at 0x40213D0: malloc (vg_replace_malloc.c:149)
==13209==    by 0x86969F5: xmalloc (xmalloc.c:147)
==13209==    by 0x39662E36: ???
Comment 6 Tobias Burnus 2007-04-03 17:54:10 UTC
Could you try the following code in ia64 and i686?

PROGRAM test
INTEGER(KIND=1) :: i(1)
i = (/ TRANSFER("a", 0_1) /)
print *, i
END PROGRAM test

I think this will compile and print "97". Is this indeed the case on ia64 adb i686?

The original program has one problem:

   i = (/ TRANSFER("a", 0_1) /)

is not well defined as "i" is kind=1 whereas "0" is kind=4.


gfortran should follow NAG f95 and print the following warning:
  Warning: x.f90, line 3: Intrinsic TRANSFER has partly undefined result

Additionally, gfortran seems to generate questionable code for "0": "i" is "0" (under x86-64) and not the expected "97". While the result is not well defined,  using "97" as do NAG f95, g95 and ifort would be highly desirable.
Comment 7 Michael Richmond 2007-04-03 18:08:30 UTC
(In reply to comment #6)
> Could you try the following code in ia64 and i686?

It works under i686. I do not have an ia64 machine.
Comment 8 Daniel Franke 2007-04-03 19:01:07 UTC
PROGRAM test
INTEGER(KIND=K) :: i(1)
i = (/ TRANSFER("a", 0_L) /)
print *, i
END PROGRAM test

Above snippet works on i686 and ia64 if K==L, if K/=L, it crashes, no matter which is the larger kind.
Comment 9 Francois-Xavier Coudert 2007-04-05 11:17:43 UTC
The segfault happens because we come into gfc_int2int to convert the value from TRANSFER into the integer(kind=1). But TRANSFER isn't simplified at this point, although it should have been, which leads to referencing memory that is not defined. This will be fixed when the gfc_simplify_transfer() function is implemented (Paul T. and Tobias B. are working on it).

Admittedly, we should have an assert() in place to prevent this kind of segfault (and have a clean ICE instead).
Comment 10 Paul Thomas 2007-05-16 06:41:29 UTC
Subject: Bug 31427

Author: pault
Date: Wed May 16 05:40:51 2007
New Revision: 124759

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=124759
Log:
2007-05-16  Brooks Moses  <brooks.moses@codesourcery.com>

	PR fortran/18769
	PR fortran/30881
	PR fortran/31194
	PR fortran/31216
	PR fortran/31427
	* target-memory.c: New file.
	* target-memory.h: New file.
	* simplify.c: Add #include "target-memory.h".
	(gfc_simplify_transfer): Implement constant-
	folding for TRANSFER intrinsic.
	* Make-lang.in: Add dependencies on new target-memory.* files.

2007-05-16  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/18769
	PR fortran/30881
	PR fortran/31194
	PR fortran/31216
	PR fortran/31427
	* transfer_simplify_1.f90: New test.
	* transfer_simplify_2.f90: New test.

Added:
    trunk/gcc/fortran/target-memory.c
    trunk/gcc/fortran/target-memory.h
    trunk/gcc/testsuite/gfortran.dg/transfer_simplify_1.f90
    trunk/gcc/testsuite/gfortran.dg/transfer_simplify_2.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/Make-lang.in
    trunk/gcc/fortran/simplify.c
    trunk/gcc/testsuite/ChangeLog

Comment 11 Paul Thomas 2007-05-16 09:15:01 UTC
Fixed on trunk

Paul and Brooks