Created attachment 33104 [details] initializes allocatable array with implied-do loop array constructor Received an 'invalid memory reference' run time error from gfortran code that initializes an allocatable array with an implied-do loop array constructor. Runs fine for Intel and Cray compilers, but fails for both GNU and PGI compilers. program pi real , allocatable :: x(:) integer :: n n = 10000 x = [ (i,i=1,n) ] print*,x(n) end
Whatever the issue was, it appears to be fixed in HEAD. troutmask:sgk[205] gfc4x -o z h.f90 troutmask:sgk[206] ./z 10000.0000 troutmask:sgk[207] gfc49 -o z h.f90 troutmask:sgk[208] ./z Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
(In reply to kargl from comment #1) > Whatever the issue was, it appears to be fixed in HEAD. > > troutmask:sgk[205] gfc4x -o z h.f90 > troutmask:sgk[206] ./z > 10000.0000 > troutmask:sgk[207] gfc49 -o z h.f90 > troutmask:sgk[208] ./z > > Program received signal SIGSEGV: Segmentation fault - invalid memory > reference. I take it back. It is broken with optimizations. troutmask:sgk[213] gfc4x -o z -O -fcheck=all h.f90 && ./z At line 6 of file h.f90 Fortran runtime error: Index '10000' of dimension 1 of array 'x' above upper bound of 1 Segmentation fault (core dumped)
> Whatever the issue was, it appears to be fixed in HEAD. I don't think so. Could you run the test with -fsanitize=address. On x86_64-apple-darwin13 r212433, I get at run time: ================================================================= ==4401==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000e014 at pc 0x1064f08c1 bp 0x7fff597100e0 sp 0x7fff597100d8 WRITE of size 4 at 0x60200000e014 thread T0 #0 0x1064f08c0 (/Users/dominiq/Documents/Fortran/g95bench/win/f90/bug/a.out+0x1000018c0) #1 0x1064f0d19 (/Users/dominiq/Documents/Fortran/g95bench/win/f90/bug/a.out+0x100001d19) #2 0x7fff922ef5fc (/usr/lib/system/libdyld.dylib+0x35fc) 0x60200000e014 is located 0 bytes to the right of 4-byte region [0x60200000e010,0x60200000e014) allocated by thread T0 here: #0 0x10652a4c9 (/opt/gcc/gcc4.10p-212433/lib/libasan.1.dylib+0x314c9) #1 0x1064f0846 (/Users/dominiq/Documents/Fortran/g95bench/win/f90/bug/a.out+0x100001846) #2 0x1064f0d19 (/Users/dominiq/Documents/Fortran/g95bench/win/f90/bug/a.out+0x100001d19) #3 0x7fff922ef5fc (/usr/lib/system/libdyld.dylib+0x35fc) SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 ?? Shadow bytes around the buggy address: 0x1c0400001bb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x1c0400001bc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x1c0400001bd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x1c0400001be0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x1c0400001bf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x1c0400001c00: fa fa[04]fa fa fa 06 fa fa fa 06 fa fa fa 05 fa 0x1c0400001c10: fa fa 00 fa fa fa 00 00 fa fa 03 fa fa fa 00 02 0x1c0400001c20: fa fa 00 07 fa fa 00 fa fa fa 00 00 fa fa 00 00 0x1c0400001c30: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00 0x1c0400001c40: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00 0x1c0400001c50: fa fa 00 00 fa fa 00 00 fa fa 00 00 fa fa 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc ASan internal: fe ==4401==ABORTING
This seems to fix it here (not heavily tested): Index: trans-expr.c =================================================================== --- trans-expr.c (révision 209169) +++ trans-expr.c (copie de travail) @@ -7932,9 +7932,7 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr /* Walk the lhs. */ lss = gfc_walk_expr (expr1); - if (gfc_is_reallocatable_lhs (expr1) - && !(expr2->expr_type == EXPR_FUNCTION - && expr2->value.function.isym != NULL)) + if (gfc_is_reallocatable_lhs (expr1)) lss->is_alloc_lhs = 1; rss = NULL; if (lss != gfc_ss_terminator)
(In reply to comment #4) > This seems to fix it here (not heavily tested): ... Confirmed, regtested without regression and no obvious problem with my other tests.
I started looking at this until I read all of the comments and realized that someone had already come up with a patch, and one that is probably better and certainly simpler than whatever I would have done. It might be worth noting that the problem seems to come up when an array is passed to an intrinsic function that returns a scalar when its argument is a scalar and that returns an array when it's passed an array. In the sample program in the description, the intrinsic function is integer to real conversion. The following sample program reproduces that problem with a simple array instead of an implied do loop, and also with the square root function. Compiling this with -fbounds-check makes the program fail on the assignment statement: program assign_allocatable implicit none call s_int_real_cvt call s_sqrt contains subroutine s_int_real_cvt implicit none integer, parameter :: r(3) = [101, 102, 103] real, allocatable :: k(:) k = r if (any(k /= r)) call abort return end subroutine subroutine s_sqrt implicit none real, parameter :: r(5) = [1, 4, 9, 16, 25] real, allocatable :: a(:) a = sqrt(r) if (any(a /= [1, 2, 3, 4, 5])) call abort return end subroutine end program Array-value intrinsics like TRANSFER and PACK don't seem to trigger this problem.
I think that this is now fixed on trunk. Don't know which patch. % gfcx -o z a.f90 && ./z 10000.0000 % gfcx -o z a.f90 -O2 -fcheck=all && ./z 10000.0000 % valgrind ./z ==85120== Memcheck, a memory error detector ==85120== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==85120== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==85120== Command: ./z ==85120== 10000.0000 ==85120== ==85120== HEAP SUMMARY: ==85120== in use at exit: 0 bytes in 0 blocks ==85120== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==85120== ==85120== All heap blocks were freed -- no leaks are possible ==85120== ==85120== For counts of detected and suppressed errors, rerun with: -v ==85120== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) I've read the tree dump for -fdump-tree-optimized and it appears to do the right think with expanding the constructor, allocating, and freeing memory. Both 6-branch and 7-branch still fail % gfc6 -o z a.f90 -O2 -fcheck=all && ./z Segmentation fault (core dumped) % gfc7 -o z a.f90 -O2 -fcheck=all && ./z Segmentation fault (core dumped) I would like to close this as fixed after committing the following testcase program pi real , allocatable :: x(:) integer :: n n = 10000 x = [ (i,i=1,n) ] if (x(n) /= 10000) stop 1 end
(In reply to kargl from comment #7) > I would like to close this as fixed after committing the following > testcase > > program pi > real , allocatable :: x(:) > integer :: n > n = 10000 > x = [ (i,i=1,n) ] > if (x(n) /= 10000) stop 1 > end Sure, go ahead.
Author: kargl Date: Wed Mar 14 00:45:45 2018 New Revision: 258509 URL: https://gcc.gnu.org/viewcvs?rev=258509&root=gcc&view=rev Log: 2018-03-13 Steven G. Kargl <kargl@gcc.gnu.org> PR fortran/61775 * gfortran.dg/pr61775.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/pr61775.f90 Modified: trunk/gcc/testsuite/ChangeLog
Closing as fixed on trunk. I've converted the code in comment #7 to a testcase, and committed it so hopefully it won't get unfixed.