https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66907

            Bug ID: 66907
           Summary: Correct code produces "Segmentation fault - invalid
                    memory reference"
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mrestelli at gmail dot com
  Target Milestone: ---

The attached code compiles with gfortran and produces an error at
runtime. As far as I can see, the code is correct. Unfortunately, I
have been unable to reduce the test further; if I try, the problem
disappears.


$ gfortran gft.f90 -g -O0 -o gft
$ ./gft 

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

Backtrace for this error:
#0  0x7F281A1F6757
#1  0x7F281A1F6D5E
#2  0x7F281972EE8F
#3  0x400A15 in __mod_a_MOD_mult at gft.f90:67
#4  0x400F44 in __mod_a_MOD_check_t_b at gft.f90:38 (discriminator 2)
#5  0x401160 in test at gft.f90:84 (discriminator 2)
Speicherzugriffsfehler

$ gfortran --version
GNU Fortran (GCC) 6.0.0 20150715 (experimental)
Copyright (C) 2015 Free Software Foundation, Inc.


The correct behaviour should be

$ ./gft 
 p(1):            1
 p(2):            1


I can see the same problem also with versions 5.1.0 and 4.9.2.




module mod_a

 implicit none

 type t_a
   integer :: i
 end type t_a

 type :: t_b
  type(t_a), allocatable :: dat(:)
 end type t_b

 interface assignment(=)
   module procedure real2t_b
 end interface

 interface operator(**)
   module procedure pow
 end interface

 interface operator(*)
   module procedure mult
 end interface

contains

 pure recursive function check_t_b(d) result(b)
  integer, intent(in) :: d
  type(t_b) :: b(2)

  type(t_b) :: xd

   xd = 1.0

   if(d.eq.1) then
     b = 1.0
   else
     b = (xd**0)*check_t_b(1)
   endif

 end function check_t_b

 elemental subroutine real2t_b(p,x)
  type(t_b), intent(out) :: p
  real, intent(in) :: x

   allocate(p%dat(1))
   p%dat%i = 1.0

 end subroutine real2t_b

 elemental function pow(p,n) result(q)
  type(t_b) :: q
  type(t_b), intent(in) :: p
  integer, intent(in) :: n

   q = 1.0

 end function pow

 elemental function mult(p1,p2) result(p)
  type(t_b), intent(in) :: p1,p2
  type(t_b) :: p

  type(t_a) :: p1_dat

   p1_dat = p1%dat(1)
   p = 1.0

 end function mult

end module mod_a

!-----------------------------------------------------------------------

program test

 use mod_a

 implicit none

 type(t_b) :: p(2)

  p = check_t_b( 2 )

  write(*,*) "p(1): ", p(1)%dat%i
  write(*,*) "p(2): ", p(2)%dat%i

end program test

Reply via email to