(j3.2006) Adventures in sections of constant arrays

Bill Long longb
Mon Mar 6 15:53:34 EST 2017

For some data points, trying 4 different compilers:

First: Intel
> ftn test.f90
> ./a.out
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source             
a.out              00000000004711D1  Unknown               Unknown  Unknown
a.out              000000000046F30B  Unknown               Unknown  Unknown
a.out              0000000000440744  Unknown               Unknown  Unknown
a.out              0000000000440556  Unknown               Unknown  Unknown
a.out              0000000000423976  Unknown               Unknown  Unknown
a.out              0000000000402166  Unknown               Unknown  Unknown
a.out              0000000000401A90  Unknown               Unknown  Unknown
a.out              0000000000400882  Unknown               Unknown  Unknown
a.out              000000000040052E  Unknown               Unknown  Unknown
a.out              000000000048BA91  Unknown               Unknown  Unknown
a.out              00000000004003A9  Unknown               Unknown  Unknown

Next: Cray
> module swap PrgEnv-intel PrgEnv-cray
> ftn test.f90
> ./a.out
Hello, world!

Next: gfortran
> module swap PrgEnv-cray PrgEnv-gnu
> ftn test.f90
> ./a.out

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x40132f in ???
	at /usr/src/packages/BUILD/glibc-2.11.3/nptl/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0
#1  0x459ed1 in ???
	at ../sysdeps/x86_64/multiarch/../memcpy.S:67
#2  0x40076d in ???
#3  0x400839 in ???
#4  0x400932 in ???
#5  0x400969 in ???
#6  0x4330a0 in __libc_start_main
	at /usr/src/packages/BUILD/glibc-2.11.3/csu/libc-start.c:242
#7  0x400544 in ???
	at ../sysdeps/x86_64/elf/start.S:113
Segmentation fault

Finally: PGI  (appears to be a different issue - not understanding the format being used).
> module swap PrgEnv-gnu PrgEnv-pgi
> ftn test.f90
> ./a.out
FIO-F-249/formatted write/unit=6/error in format - illegal E, F, G or D descriptor.
 File name = stdout     formatted, sequential access   record = 1
 In source file test.f90, at line number 13

So, it is possible, although uncommon, to get this to work. 


On Mar 6, 2017, at 2:31 PM, Steve Lionel <steve at stevelionel.com> wrote:

> Consider the following program, submitted by James VanBuskirk:
> module constants
>    implicit none
>    character, parameter :: hello*(*) = 'Hello, world!'//achar(0)
> end module constants
> module funcs
>    implicit none
>    contains
>       subroutine trashme(string,length)
>          integer length
>          character string(length)
>          call trashme2(string(:length:2))
>          write(*,'(*(g0))') string(:length)
>       end subroutine trashme
>       subroutine trashme2(array)
>          character array(:)
>          call trashme3(array)
>       end subroutine trashme2
> end module funcs
> subroutine trashme3(array)
>    implicit none
>    character array(*)
> end subroutine trashme3
> program test
>    use constants
>    use funcs
>    implicit none
>    call trashme(hello, index(hello,achar(0))-1)
> end program test
> The main program passes a character constant to procedure trashme, which accepts it as an explicit-shape array of characters. This is allowed (17-007, p3-4.) trashme then passes a discontiguous array section to trashme2, which declares the dummy argument as a deferred-shape array of single characters.  trashme2 then passes its argument to trashme3, where the corresponding dummy is an assumed-size character array (also allowed). Because an assumed-size array must be contiguous, the processor has to check whether the actual argument is contiguous, and if not (which it isn't here), do copy-in/copy-out. It's the copy-out that gets us into trouble.
> If trashme3's dummy had INTENT(INOUT) or INTENT(OUT), the associated actual argument must be definable, which it isn't here. But since there is no INTENT, that restriction does not apply. Because trashme3 might redefine the dummy, the copy has to be written back to the actual on return from trashme3 - but as it's a constant, that (typically) produces a segfault/access violation.
> I haven't been able to find any language in the standard that this code violates, yet I also can't figure out how a compiler could possibly support it. Did I miss a trick somewhere? If the standard indeed does not prohibit this code, should it - and how should such a restriction be worded? It couldn't be a constraint. Note that the array never gets redefined here, so it can't be a restriction on redefinition.
> Steve
> _______________________________________________
> J3 mailing list
> J3 at mailman.j3-fortran.org
> http://mailman.j3-fortran.org/mailman/listinfo/j3

Bill Long                                                                       longb at cray.com
Fortran Technical Support  &                                  voice:  651-605-9024
Bioinformatics Software Development                     fax:  651-605-9142
Cray Inc./ Cray Plaza, Suite 210/ 380 Jackson St./ St. Paul, MN 55101

More information about the J3 mailing list