https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71544
Bug ID: 71544 Summary: gfortran compiler optimization bug when dealing with c-style pointers Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: fortran Assignee: unassigned at gcc dot gnu.org Reporter: fortranbug at gmail dot com Target Milestone: --- The code below produces different results with gfortran with -O1 as compared with -O0, -O2, and -O3. We've tested this with gfortran versions 4.8, 4.9, 5.2 and 5.3 and seen the same behavior in all cases. An even older version, 4.4.7 shipped with CentOS 6, works as expected for all optimization levels. A local pointer "a" in subroutine init() is used to allocate memory and its location is stored in a c-pointer "cptr", which is saved in a module. An assignment "a=100" at the end of the init() routine is apparently removed by the -O1 optimizer as dead code, but kept for -O0, -O2 and -O3. When it works (-O0, -O2, -O3), the initialization takes effect and the program prints “100" in its second line. When it doesn't (-O1), it prints 0. We discussed this behavior on comp.lang.fortran https://groups.google.com/forum/#!topic/comp.lang.fortran/wyMy8PqeVxA and the consensus was that this is indeed an optimization bug. The bottom line is that there does not appear to be any reason in the standard to expect that the data pointed to by ‘a' would become invalid at the end of init(), and the compiler should detect that the call to save_cptr() _can_ be creating an alias (and in fact it is), and not treat the "a = 100" statement as dead code to be eliminated. The specific parts of the standard that support this interpretation are best summarized in Richard Maine's Jun 11 post in the aforementioned comp.lang.fortran thread. --------------------------- module store_cptr use, intrinsic :: iso_c_binding implicit none public type(c_ptr), save :: cptr end module store_cptr subroutine init() use, intrinsic :: iso_c_binding implicit none integer(c_int), pointer :: a allocate(a) call save_cptr(c_loc(a)) a = 100 end subroutine init subroutine save_cptr(cptr_in) use store_cptr implicit none type(c_ptr), intent(in) :: cptr_in cptr = cptr_in end subroutine save_cptr program init_fails use store_cptr implicit none integer(c_int), pointer :: val call init() call c_f_pointer(cptr,val) print *,'The following line should print 100' print *,val end program init_fails ---------------------------