为什么我在Fortran中的类型中有随机返回值,-O2?

Seb*_*yer 3 gcc fortran compiler-optimization

在我的小代码示例中,当我使用-O2优化进行编译时,我有变量testvar%bed的随机值.

gfortran -O2 test.F90
Run Code Online (Sandbox Code Playgroud)

编辑 以使问题更清晰:

所以问题是,我打印testvar%bed,并显示随机垃圾,每次运行都会发生变化(不可打印的字符,如?????).它应该是打印bed.

这只发生在某些系统上.上

  • debian gcc 4.9.1 - 没关系
  • osx gcc 4.9.1 - 好的
  • ubuntu gcc 4.9.1 - 随机值
  • arch gcc 4.9.2 - 随机值

如果在代码中调用该函数两次,则会发生这种情况.如果我评论第二个电话,一切都好了.如果我在函数末尾放置一个任意的print语句,我也可以"修复"这个问题.

编辑 回复@tkoenig

仅使用-O1或不使用任何优化都不会发生此问题.它确实发生-O1 -fgcse但不仅仅发生-fgcse.仅-ffrontend-optimize单独使用不会导致错误.

我错过了什么?

program testbug
  implicit none
  integer, parameter :: STRLEN = 256
  type :: ncVarnames_t
    ! variables names for the different ice models
    character (len=STRLEN) :: surf
    character (len=STRLEN) :: x, y
    character (len=STRLEN) :: bed
    character (len=STRLEN) :: thick
  end type ncVarnames_t

  type (ncVarnames_t) :: testvar
  type (ncVarnames_t) :: testvar2

  print *, "hello"

  testvar = get_ncVarnames ("test")
  testvar2 = get_ncVarnames ("test")

  print *, trim(testvar%surf)
  print *, trim(testvar%bed)
  print *, trim(testvar%bed)
  print *, trim(testvar%surf)

  contains
  type (ncVarnames_t) function get_ncVarnames (model) result (v)
    character(len=*), intent(in) :: model
    ! type (ncVarnames_t)          :: v

    select case (model)
      case ("test")
        ! test model
        v%x = 'x'
        v%y = 'y'
        v%surf = 'surf'
        v%bed = 'bed'
       case ("pism")
         ! pism data
         v%x = 'x'
         v%y = 'y'
         v%surf = 'usurf'
         v%bed = 'topg'
      case default
        print *, "unknown model, please use one of [test pism sico]"
        stop
    end select
  end function get_ncVarnames
end program testbug
Run Code Online (Sandbox Code Playgroud)

小智 5

看起来像gfortran/gcc bug,可能需要一些特殊情况才能触发(这就是为什么不是每个人都能够重现它).

我也复制了这个并提交了PR 65504.这是对4.8的回归,所以应该特别注意.修复也应该向后移植到4.9.

解决方法(在PR中进行分析):使用-fno-dse.