Skip to content

Commit 3b276fe

Browse files
committed
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.
1 parent 117782e commit 3b276fe

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

gcc/fortran/resolve.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8740,8 +8740,25 @@ static bool
87408740
conformable_arrays (gfc_expr *e1, gfc_expr *e2)
87418741
{
87428742
gfc_ref *tail;
8743+
bool scalar;
8744+
87438745
for (tail = e2->ref; tail && tail->next; tail = tail->next);
87448746

8747+
/* If MOLD= is present and is not scalar, and the allocate-object has an
8748+
explicit-shape-spec, the ranks need not agree. This may be unintended,
8749+
so let's emit a warning if -Wsurprising is given. */
8750+
scalar = !tail || tail->type == REF_COMPONENT;
8751+
if (e1->mold && e1->rank > 0
8752+
&& (scalar || (tail->type == REF_ARRAY && tail->u.ar.type != AR_FULL)))
8753+
{
8754+
if (scalar || (tail->u.ar.as && e1->rank != tail->u.ar.as->rank))
8755+
gfc_warning (OPT_Wsurprising, "Allocate-object at %L has rank %d "
8756+
"but MOLD= expression at %L has rank %d",
8757+
&e2->where, scalar ? 0 : tail->u.ar.as->rank,
8758+
&e1->where, e1->rank);
8759+
return true;
8760+
}
8761+
87458762
/* First compare rank. */
87468763
if ((tail && (!tail->u.ar.as || e1->rank != tail->u.ar.as->rank))
87478764
|| (!tail && e1->rank != e2->rank))
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
! { dg-do compile }
2+
! { dg-additional-options "-Wsurprising" }
3+
!
4+
! PR fortran/51961 - fix checking of MOLD= in ALLOCATE statements
5+
!
6+
! Contributed by Tobias Burnus
7+
8+
program p
9+
implicit none
10+
type t
11+
end type t
12+
type u
13+
class(t), allocatable :: a(:), b(:,:), c
14+
end type u
15+
class(T), allocatable :: a(:), b(:,:), c
16+
type(u) :: z
17+
18+
allocate (b(2,2))
19+
allocate (z% b(2,2))
20+
21+
allocate (a(2), mold=b(:,1))
22+
allocate (a(1:2), mold=b(1,:))
23+
allocate (a(2), mold=b) ! { dg-warning "but MOLD= expression at" }
24+
allocate (a(1:2), mold=b) ! { dg-warning "but MOLD= expression at" }
25+
allocate (z% a(2), mold=b(:,1))
26+
allocate (z% a(1:2), mold=b(1,:))
27+
allocate (z% a(2), mold=b) ! { dg-warning "but MOLD= expression at" }
28+
allocate (z% a(1:2), mold=b) ! { dg-warning "but MOLD= expression at" }
29+
allocate (z% a(2), mold=z% b(:,1))
30+
allocate (z% a(1:2), mold=z% b(1,:))
31+
allocate (z% a(2), mold=z% b) ! { dg-warning "but MOLD= expression at" }
32+
allocate (z% a(1:2), mold=z% b) ! { dg-warning "but MOLD= expression at" }
33+
34+
allocate (c, mold=b(1,1))
35+
allocate (c, mold=b) ! { dg-warning "but MOLD= expression at" }
36+
allocate (z% c, mold=b(1,1))
37+
allocate (z% c, mold=b) ! { dg-warning "but MOLD= expression at" }
38+
allocate (z% c, mold=z% b(1,1))
39+
allocate (z% c, mold=z% b) ! { dg-warning "but MOLD= expression at" }
40+
41+
allocate (a, mold=b(:,1))
42+
allocate (a, mold=b(1,:))
43+
allocate (z% a, mold=b(:,1))
44+
allocate (z% a, mold=b(1,:))
45+
allocate (z% a, mold=z% b(:,1))
46+
allocate (z% a, mold=z% b(1,:))
47+
48+
allocate (a, mold=b) ! { dg-error "or have the same rank" }
49+
allocate (z% a, mold=b) ! { dg-error "or have the same rank" }
50+
allocate (z% a, mold=z% b) ! { dg-error "or have the same rank" }
51+
end

0 commit comments

Comments
 (0)