Skip to content

Commit 80d126b

Browse files
Steve Karglharald-anlauf
Steve Kargl
andcommitted
Fortran: ALLOCATE statement, SOURCE/MOLD expressions with subrefs [PR114024]
PR fortran/114024 gcc/fortran/ChangeLog: * trans-stmt.cc (gfc_trans_allocate): When a source expression has substring references, part-refs, or %re/%im inquiries, wrap the entity in parentheses to force evaluation of the expression. gcc/testsuite/ChangeLog: * gfortran.dg/allocate_with_source_27.f90: New test. * gfortran.dg/allocate_with_source_28.f90: New test. Co-Authored-By: Harald Anlauf <[email protected]>
1 parent 85c12ae commit 80d126b

File tree

3 files changed

+118
-2
lines changed

3 files changed

+118
-2
lines changed

gcc/fortran/trans-stmt.cc

+8-2
Original file line numberDiff line numberDiff line change
@@ -6355,8 +6355,14 @@ gfc_trans_allocate (gfc_code * code, gfc_omp_namelist *omp_allocate)
63556355
vtab_needed = (al->expr->ts.type == BT_CLASS);
63566356

63576357
gfc_init_se (&se, NULL);
6358-
/* When expr3 is a variable, i.e., a very simple expression,
6359-
then convert it once here. */
6358+
/* When expr3 is a variable, i.e., a very simple expression, then
6359+
convert it once here. If one has a source expression that has
6360+
substring references, part-refs, or %re/%im inquiries, wrap the
6361+
entity in parentheses to force evaluation of the expression. */
6362+
if (code->expr3->expr_type == EXPR_VARIABLE
6363+
&& is_subref_array (code->expr3))
6364+
code->expr3 = gfc_get_parentheses (code->expr3);
6365+
63606366
if (code->expr3->expr_type == EXPR_VARIABLE
63616367
|| code->expr3->expr_type == EXPR_ARRAY
63626368
|| code->expr3->expr_type == EXPR_CONSTANT)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
!
2+
! { dg-do run }
3+
!
4+
! fortran/PR114024
5+
! https://github.com/fujitsu/compiler-test-suite
6+
! Modified from Fortran/0093/0093_0130.f90
7+
!
8+
program foo
9+
implicit none
10+
complex :: cmp(3)
11+
real, allocatable :: xx(:), yy(:), zz(:)
12+
cmp = (3., 6.78)
13+
allocate(xx, source = cmp%re) ! This caused an ICE.
14+
allocate(yy, source = cmp(1:3)%re) ! This caused an ICE.
15+
allocate(zz, source = (cmp%re))
16+
if (any(xx /= [3., 3., 3.])) stop 1
17+
if (any(yy /= [3., 3., 3.])) stop 2
18+
if (any(zz /= [3., 3., 3.])) stop 3
19+
end program foo
20+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
! { dg-do run }
2+
!
3+
! PR fortran/114024
4+
5+
program foo
6+
implicit none
7+
complex :: cmp(3) = (3.,4.)
8+
type ci ! pseudo "complex integer" type
9+
integer :: re
10+
integer :: im
11+
end type ci
12+
type cr ! pseudo "complex" type
13+
real :: re
14+
real :: im
15+
end type cr
16+
type u
17+
type(ci) :: ii(3)
18+
type(cr) :: rr(3)
19+
end type u
20+
type(u) :: cc
21+
22+
cc% ii% re = nint (cmp% re)
23+
cc% ii% im = nint (cmp% im)
24+
cc% rr% re = cmp% re
25+
cc% rr% im = cmp% im
26+
27+
call test_substring ()
28+
call test_int_real ()
29+
call test_poly ()
30+
31+
contains
32+
33+
subroutine test_substring ()
34+
character(4) :: str(3) = ["abcd","efgh","ijkl"]
35+
character(:), allocatable :: ac(:)
36+
allocate (ac, source=str(1::2)(2:4))
37+
if (size (ac) /= 2 .or. len (ac) /= 3) stop 11
38+
if (ac(2) /= "jkl") stop 12
39+
deallocate (ac)
40+
allocate (ac, mold=str(1::2)(2:4))
41+
if (size (ac) /= 2 .or. len (ac) /= 3) stop 13
42+
deallocate (ac)
43+
end
44+
45+
subroutine test_int_real ()
46+
integer, allocatable :: aa(:)
47+
real, pointer :: pp(:)
48+
allocate (aa, source = cc% ii% im)
49+
if (size (aa) /= 3) stop 21
50+
if (any (aa /= cmp% im)) stop 22
51+
allocate (pp, source = cc% rr% re)
52+
if (size (pp) /= 3) stop 23
53+
if (any (pp /= cmp% re)) stop 24
54+
deallocate (aa, pp)
55+
end
56+
57+
subroutine test_poly ()
58+
class(*), allocatable :: uu(:), vv(:)
59+
allocate (uu, source = cc% ii% im)
60+
allocate (vv, source = cc% rr% re)
61+
if (size (uu) /= 3) stop 31
62+
if (size (vv) /= 3) stop 32
63+
call check (uu)
64+
call check (vv)
65+
deallocate (uu, vv)
66+
allocate (uu, mold = cc% ii% im)
67+
allocate (vv, mold = cc% rr% re)
68+
if (size (uu) /= 3) stop 33
69+
if (size (vv) /= 3) stop 34
70+
deallocate (uu, vv)
71+
end
72+
73+
subroutine check (x)
74+
class(*), intent(in) :: x(:)
75+
select type (x)
76+
type is (integer)
77+
if (any (x /= cmp% im)) then
78+
print *, "'integer':", x
79+
stop 41
80+
end if
81+
type is (real)
82+
if (any (x /= cmp% re)) then
83+
print *, "'real':", x
84+
stop 42
85+
end if
86+
type is (character(*))
87+
print *, "'character':", x
88+
end select
89+
end
90+
end

0 commit comments

Comments
 (0)