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

--- Comment #51 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jerry DeLisle <[email protected]>:

https://gcc.gnu.org/g:eaf4292c83804bd21b920db174401ca3702601d4

commit r17-1352-geaf4292c83804bd21b920db174401ca3702601d4
Author: Jerry DeLisle <[email protected]>
Date:   Thu Jun 4 12:11:37 2026 -0700

    Fortran: fix stack-buffer-overflow passing type to assumed-rank class
[PR60576]

    Two code paths copied a full GFC_MAX_DIMENSIONS dim[] array from a
    descriptor that physically holds only dtype.rank dimensions, triggering
    a stack-buffer-overflow detected by AddressSanitizer.

    Case 1 - assumed-rank type(T) dummy passed to class(T) assumed-rank:
    The caller only allocates storage for dtype.rank dimensions.  The code
    generated a static GFC_MAX_DIMENSIONS struct copy of the dim[] array,
    reading past the physical end of the descriptor.  Fix by checking
    expr->rank == -1 and replacing the static copy with a runtime-sized
    __builtin_memcpy of dtype.rank * sizeof(descriptor_dimension) bytes.

    Case 2 - fixed-rank type(T) actual passed directly to class(T)
assumed-rank:
    gfortran uses a rank-specific descriptor type for fixed-rank type arrays
    (dim[rank] rather than dim[GFC_MAX_DIMENSIONS]).  The class assumed-rank
    formal's descriptor has dim_t[GFC_MAX_DIMENSIONS].  The call to
    gfc_class_array_data_assign with lhs_type=true keyed the ARRAY_RANGE_REF
    off TREE_TYPE(lhs_dim) = dim_t[GFC_MAX_DIMENSIONS], reading 15*24 = 360
    bytes from a descriptor that physically has only rank*24 bytes for the
    dim[] array.  Fix by checking CLASS_DATA(fsym)->as->rank == -1 and
    passing lhs_type=false so the ARRAY_RANGE_REF is sized by
    TREE_TYPE(rhs_dim) = dim_t[rank], copying only the physically present
    entries.  Fixed-rank class formals retain lhs_type=true.

    Assisted by: Claude Sonnet 4.6

            PR fortran/60576

    gcc/fortran/ChangeLog:

            PR fortran/60576
            * trans-array.cc (gfc_conv_array_parameter): For an assumed-rank
            actual argument passed to a CLASS assumed-rank formal, use a
            runtime-sized memcpy for the dim[] entries instead of a full
            GFC_MAX_DIMENSIONS static copy.  For a fixed-rank actual to a
            CLASS assumed-rank formal, pass lhs_type=false to
            gfc_class_array_data_assign so the dim[] copy is sized by the
            RHS descriptor type (dim_t[rank]).  Fixed-rank class formals
            retain lhs_type=true.
            * trans-expr.cc (gfc_conv_derived_to_class): For an assumed-rank
            actual, use a runtime-sized memcpy for the derived_array descriptor
            dim[] copy instead of a full GFC_MAX_DIMENSIONS static copy.

    gcc/testsuite/ChangeLog:

            PR fortran/60576
            * gfortran.dg/asan/assumed_rank_26.f90: New test covering both
            assumed-rank and fixed-rank type actuals passed to a CLASS
            assumed-rank dummy.

Reply via email to