Skip to content

[flang] Behavior of gfortran test depends on optimization level: pr117797.f90 #139754

Open
@tarunprabhu

Description

@tarunprabhu

Steps to reproduce:

Assuming that the LLVM test suite is checked out in ./llvm-test-suite, compile the test at various optimization levels

$ flang -o a0.out -O0 ./llvm-test-suite/Fortran/gfortran/regression/pr117797.f90
$ flang -o a1.out -O1 ./llvm-test-suite/Fortran/gfortran/regression/pr117797.f90
$ flang -o a2.out -O2 ./llvm-test-suite/Fortran/gfortran/regression/pr117797.f90
$ flang -o a3.out -O3 ./llvm-test-suite/Fortran/gfortran/regression/pr117797.f90
$ flang -o alto.out -flto=auto ./llvm-test-suite/Fortran/gfortran/regression/pr117797.f90

When these are run, the executables created with -O0 and -flto=auto encounter a STOP statement in the code, but those compiled with optimizations do not.

$ ./a0.out 
Fortran STOP: code 2
$ ./a1.out
$ ./a2.out
$ ./a3.out
$ ./alto.out
Fortran STOP: code 2

Expected behavior: The stop message should never be printed.

What follows is a slightly reduced from the original but that reproduces this behavior.

module foo

  type, public :: any_matrix
    class(*), allocatable :: value(:,:)
  end type

contains

  function bar(this) result(uptr)
    class(any_matrix), target, intent(in) :: this
    class(*), pointer :: uptr(:,:)
    uptr => this%value ! Seg. fault in trans-array.cc(gfc_get_array_span) here
  end function

  function build(this) result (res)
    class(*) :: this(:,:)
    type(any_matrix) :: res
    res%value = this
  end function

  function evaluate (this) result (res)
    class(*) :: this(:,:)
    character(len = 2, kind = 1), allocatable :: res(:)
      select type (ans => this)
        type is (character(*))
          res = reshape (ans, [4])
        type is (integer)
          allocate (res (8))
          write (res, '(i2)') ans
        class default
          res = ['no','t ','OK','!!']
      end select
  end

end module

  use foo
  class(*), allocatable :: up (:, :)
  integer :: i(2,2) = reshape ([1,2,3,4], [2,2])

  up = bar (build (i))
  if (any (evaluate (up) /= [' 1',' 2',' 3',' 4'])) stop 2

  deallocate (up)
end

The cases in the SELECT statement seem to have an effect on the behavior. Removing only the character(*) case results in correct behavior at all optimization levels. Removing only the class default cases causes the error to occur only at -O0 but not at any other optimization level.

[EDIT]: Remove redundant statement and clarify what effect modifying the SELECT construct has on behavior

Metadata

Metadata

Assignees

No one assigned

    Labels

    flangFlang issues not falling into any other category

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions