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

            Bug ID: 121683
           Summary: Data corruption with sourced allocation from
                    constructor
           Product: gcc
           Version: 15.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: neil.n.carlson at gmail dot com
  Target Milestone: ---

The compiler is generating bad code for the sourced allocation line in the
following example. It is corrupting the INTENT(IN) dummy variable F which
appears in the SOURCE expression. ASAN output suggests that components of F are
incorrectly freed by the code generated for the statement.

module mod

  implicit none

  type, abstract :: func
  end type

  type, extends(func) :: poly
    real, allocatable :: array(:)
  end type

  type, extends(func) :: func_deriv
    class(func), allocatable :: f
  end type

contains

  subroutine alloc_deriv(f, df)
    class(func), intent(in) :: f
    class(func), allocatable, intent(out) :: df
    allocate(df, source=func_deriv(f)) ! THIS CORRUPTS F
  end subroutine

end module

program fubar

  use mod

  type(poly), allocatable :: p
  class(func), allocatable :: f, df
  real, parameter :: array(*) = [1, 2]

  allocate(p)
  p%array = array
  call move_alloc(p, f)
  call alloc_deriv(f, df)

  if (.not.allocated(f)) stop 1

  select type (f)
  type is (poly)
    if (.not.allocated(f%array)) stop 2 ! SANITIZER: HEAP-USE-AFTER-FREE
    if (size(f%array) /= size(array)) stop 3
    if (any(f%array /= array)) stop 4 ! SEGFAULTS HERE WITHOUT SANITIZER
  class default
    stop 5
  end select

end

Here's the output from the sanitizer:

$ gfortran -g -fsanitize=address gfortran-20250826.f90 
$ ./a.out
=================================================================
==3685==ERROR: AddressSanitizer: heap-use-after-free on address 0x7bcc94be0020
at pc 0x0000004040f7 bp 0x7fffa9c3b340 sp 0x7fffa9c3b338
READ of size 8 at 0x7bcc94be0020 thread T0
    #0 0x0000004040f6 in fubar /tmp/gfortran-20250826.f90:43
    #1 0x0000004043b6 in main /tmp/gfortran-20250826.f90:28
    #2 0x7f6c95e0f487 in __libc_start_call_main (/lib64/libc.so.6+0x3487)
(BuildId: 1fe4f71c184938b1af3656d8b8cdb4928ab12394)
    #3 0x7f6c95e0f54a in __libc_start_main@GLIBC_2.2.5
(/lib64/libc.so.6+0x354a) (BuildId: 1fe4f71c184938b1af3656d8b8cdb4928ab12394)
    #4 0x0000004011f4 in _start (/tmp/a.out+0x4011f4)

0x7bcc94be0020 is located 0 bytes inside of 64-byte region
[0x7bcc94be0020,0x7bcc94be0060)
freed by thread T0 here:
    #0 0x7f6c964e6a6b in free
../../../../libsanitizer/asan/asan_malloc_linux.cpp:51
    #1 0x000000403429 in __mod_MOD_alloc_deriv /tmp/gfortran-20250826.f90:21
    #2 0x000000404097 in fubar /tmp/gfortran-20250826.f90:37
    #3 0x0000004043b6 in main /tmp/gfortran-20250826.f90:28
    #4 0x7f6c95e0f487 in __libc_start_call_main (/lib64/libc.so.6+0x3487)
(BuildId: 1fe4f71c184938b1af3656d8b8cdb4928ab12394)
    #5 0x7f6c95e0f54a in __libc_start_main@GLIBC_2.2.5
(/lib64/libc.so.6+0x354a) (BuildId: 1fe4f71c184938b1af3656d8b8cdb4928ab12394)
    #6 0x0000004011f4 in _start (/tmp/a.out+0x4011f4)

previously allocated by thread T0 here:
    #0 0x7f6c964e7dab in malloc
../../../../libsanitizer/asan/asan_malloc_linux.cpp:67
    #1 0x0000004035f8 in fubar /tmp/gfortran-20250826.f90:34
    #2 0x0000004043b6 in main /tmp/gfortran-20250826.f90:28
    #3 0x7f6c95e0f487 in __libc_start_call_main (/lib64/libc.so.6+0x3487)
(BuildId: 1fe4f71c184938b1af3656d8b8cdb4928ab12394)
    #4 0x7f6c95e0f54a in __libc_start_main@GLIBC_2.2.5
(/lib64/libc.so.6+0x354a) (BuildId: 1fe4f71c184938b1af3656d8b8cdb4928ab12394)
    #5 0x0000004011f4 in _start (/tmp/a.out+0x4011f4)

SUMMARY: AddressSanitizer: heap-use-after-free /tmp/gfortran-20250826.f90:43 in
fubar
Shadow bytes around the buggy address:
  0x7bcc94bdfd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7bcc94bdfe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7bcc94bdfe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7bcc94bdff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7bcc94bdff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x7bcc94be0000: fa fa fa fa[fd]fd fd fd fd fd fd fd fa fa fa fa
  0x7bcc94be0080: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
  0x7bcc94be0100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7bcc94be0180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7bcc94be0200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7bcc94be0280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==3685==ABORTING

Reply via email to