https://gcc.gnu.org/g:3b276fe0d22f9052657dbbffbb8ad6f8585bd304
commit r16-1528-g3b276fe0d22f9052657dbbffbb8ad6f8585bd304 Author: Harald Anlauf <anl...@gmx.de> Date: Sun Jun 15 21:09:28 2025 +0200 Fortran: fix checking of MOLD= in ALLOCATE statements [PR51961] In ALLOCATE statements where the MOLD= argument is present and is not scalar, and the allocate-object has an explicit-shape-spec, the standard does not require the ranks to agree. In that case we skip the rank check, but emit a warning if -Wsurprising is given. PR fortran/51961 gcc/fortran/ChangeLog: * resolve.cc (conformable_arrays): Use modified rank check when MOLD= expression is given. gcc/testsuite/ChangeLog: * gfortran.dg/allocate_with_mold_5.f90: New test. Diff: --- gcc/fortran/resolve.cc | 17 ++++++++ gcc/testsuite/gfortran.dg/allocate_with_mold_5.f90 | 51 ++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index d09aef0a899c..5413d8f9c542 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -8740,8 +8740,25 @@ static bool conformable_arrays (gfc_expr *e1, gfc_expr *e2) { gfc_ref *tail; + bool scalar; + for (tail = e2->ref; tail && tail->next; tail = tail->next); + /* If MOLD= is present and is not scalar, and the allocate-object has an + explicit-shape-spec, the ranks need not agree. This may be unintended, + so let's emit a warning if -Wsurprising is given. */ + scalar = !tail || tail->type == REF_COMPONENT; + if (e1->mold && e1->rank > 0 + && (scalar || (tail->type == REF_ARRAY && tail->u.ar.type != AR_FULL))) + { + if (scalar || (tail->u.ar.as && e1->rank != tail->u.ar.as->rank)) + gfc_warning (OPT_Wsurprising, "Allocate-object at %L has rank %d " + "but MOLD= expression at %L has rank %d", + &e2->where, scalar ? 0 : tail->u.ar.as->rank, + &e1->where, e1->rank); + return true; + } + /* First compare rank. */ if ((tail && (!tail->u.ar.as || e1->rank != tail->u.ar.as->rank)) || (!tail && e1->rank != e2->rank)) diff --git a/gcc/testsuite/gfortran.dg/allocate_with_mold_5.f90 b/gcc/testsuite/gfortran.dg/allocate_with_mold_5.f90 new file mode 100644 index 000000000000..f5e2fc93d0a4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/allocate_with_mold_5.f90 @@ -0,0 +1,51 @@ +! { dg-do compile } +! { dg-additional-options "-Wsurprising" } +! +! PR fortran/51961 - fix checking of MOLD= in ALLOCATE statements +! +! Contributed by Tobias Burnus + +program p + implicit none + type t + end type t + type u + class(t), allocatable :: a(:), b(:,:), c + end type u + class(T), allocatable :: a(:), b(:,:), c + type(u) :: z + + allocate (b(2,2)) + allocate (z% b(2,2)) + + allocate (a(2), mold=b(:,1)) + allocate (a(1:2), mold=b(1,:)) + allocate (a(2), mold=b) ! { dg-warning "but MOLD= expression at" } + allocate (a(1:2), mold=b) ! { dg-warning "but MOLD= expression at" } + allocate (z% a(2), mold=b(:,1)) + allocate (z% a(1:2), mold=b(1,:)) + allocate (z% a(2), mold=b) ! { dg-warning "but MOLD= expression at" } + allocate (z% a(1:2), mold=b) ! { dg-warning "but MOLD= expression at" } + allocate (z% a(2), mold=z% b(:,1)) + allocate (z% a(1:2), mold=z% b(1,:)) + allocate (z% a(2), mold=z% b) ! { dg-warning "but MOLD= expression at" } + allocate (z% a(1:2), mold=z% b) ! { dg-warning "but MOLD= expression at" } + + allocate (c, mold=b(1,1)) + allocate (c, mold=b) ! { dg-warning "but MOLD= expression at" } + allocate (z% c, mold=b(1,1)) + allocate (z% c, mold=b) ! { dg-warning "but MOLD= expression at" } + allocate (z% c, mold=z% b(1,1)) + allocate (z% c, mold=z% b) ! { dg-warning "but MOLD= expression at" } + + allocate (a, mold=b(:,1)) + allocate (a, mold=b(1,:)) + allocate (z% a, mold=b(:,1)) + allocate (z% a, mold=b(1,:)) + allocate (z% a, mold=z% b(:,1)) + allocate (z% a, mold=z% b(1,:)) + + allocate (a, mold=b) ! { dg-error "or have the same rank" } + allocate (z% a, mold=b) ! { dg-error "or have the same rank" } + allocate (z% a, mold=z% b) ! { dg-error "or have the same rank" } +end