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

            Bug ID: 128397
           Summary: Uninitialized extent of automatic array sized by SIZE
                    of another when used in contained procedure
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: albert at tugraz dot at
                CC: albert at tugraz dot at, jvdelisle at gcc dot gnu.org
  Target Milestone: ---

An automatic array whose bound is SIZE or UBOUND of another automatic
array of the same procedure gets an uninitialized extent when a
contained procedure references it.

module m
  implicit none
contains
  subroutine matcher (n)
    integer, intent(in) :: n
    real :: oracle(n)
    logical :: candidates(size (oracle))
    print *, 'expected extents: 3 3; actual:', size (oracle), size (candidates)
    if (size (candidates) /= 3) error stop 'wrong extent'
  contains
    logical function assigned ()
      assigned = candidates(1)
    end function
  end subroutine
end module

program p
  use m
  call matcher (3)
end program

$ gfortran -O2 pr.f90 && ./a.out
 expected extents: 3 3; actual:           3           0
ERROR STOP wrong extent

The value is uninitialized and varies between runs (0 or garbage on
x86_64-linux); with garbage, -fcheck=bounds does not fire.  This
testcase fails with 16.2.1 and r17-5872-g0841d1b8c9e at -O0 and -O2; a
slightly larger form of it also failed with 11.4, 12.2 and 13.3.  Not a
regression as far as tested.  The extent is correct when assigned
does not reference candidates, or with candidates(n).

-fdump-tree-original of matcher, in emission order:

  ubound.0 = ... MAX_EXPR <(parm.8.dim[0].ubound - parm.8.dim[0].lbound) + 1,
0>;
  ...
  ubound.2 = (integer(kind=8)) *n;

The extent of candidates (ubound.0) is computed from parm.8, built from
ubound.2, the upper bound of oracle, before ubound.2 is assigned from n.

gfc_generate_function_code translates the contained procedures before
generate_local_vars, so the reference in assigned creates the decl of
candidates, and defers its setup, before that of oracle.
gfc_defer_symbol_init orders the deferred-init chain only for dummy
arguments and for the fn_result_dep case added for PR59104; every other
variable keeps creation order.

The reduction, the analysis and this report were prepared with AI
assistance (Claude).  I reran the testcase and checked the analysis
against trans-decl.cc.  A patch follows.

Reply via email to