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 <anlauf@gmx.de>
This commit is contained in:
parent
85c12ae8b8
commit
80d126ba99
3 changed files with 118 additions and 2 deletions
|
@ -6355,8 +6355,14 @@ gfc_trans_allocate (gfc_code * code, gfc_omp_namelist *omp_allocate)
|
|||
vtab_needed = (al->expr->ts.type == BT_CLASS);
|
||||
|
||||
gfc_init_se (&se, NULL);
|
||||
/* When expr3 is a variable, i.e., a very simple expression,
|
||||
then convert it once here. */
|
||||
/* When expr3 is a variable, i.e., a very simple expression, then
|
||||
convert it once here. If one has a source expression that has
|
||||
substring references, part-refs, or %re/%im inquiries, wrap the
|
||||
entity in parentheses to force evaluation of the expression. */
|
||||
if (code->expr3->expr_type == EXPR_VARIABLE
|
||||
&& is_subref_array (code->expr3))
|
||||
code->expr3 = gfc_get_parentheses (code->expr3);
|
||||
|
||||
if (code->expr3->expr_type == EXPR_VARIABLE
|
||||
|| code->expr3->expr_type == EXPR_ARRAY
|
||||
|| code->expr3->expr_type == EXPR_CONSTANT)
|
||||
|
|
20
gcc/testsuite/gfortran.dg/allocate_with_source_27.f90
Normal file
20
gcc/testsuite/gfortran.dg/allocate_with_source_27.f90
Normal file
|
@ -0,0 +1,20 @@
|
|||
!
|
||||
! { dg-do run }
|
||||
!
|
||||
! fortran/PR114024
|
||||
! https://github.com/fujitsu/compiler-test-suite
|
||||
! Modified from Fortran/0093/0093_0130.f90
|
||||
!
|
||||
program foo
|
||||
implicit none
|
||||
complex :: cmp(3)
|
||||
real, allocatable :: xx(:), yy(:), zz(:)
|
||||
cmp = (3., 6.78)
|
||||
allocate(xx, source = cmp%re) ! This caused an ICE.
|
||||
allocate(yy, source = cmp(1:3)%re) ! This caused an ICE.
|
||||
allocate(zz, source = (cmp%re))
|
||||
if (any(xx /= [3., 3., 3.])) stop 1
|
||||
if (any(yy /= [3., 3., 3.])) stop 2
|
||||
if (any(zz /= [3., 3., 3.])) stop 3
|
||||
end program foo
|
||||
|
90
gcc/testsuite/gfortran.dg/allocate_with_source_28.f90
Normal file
90
gcc/testsuite/gfortran.dg/allocate_with_source_28.f90
Normal file
|
@ -0,0 +1,90 @@
|
|||
! { dg-do run }
|
||||
!
|
||||
! PR fortran/114024
|
||||
|
||||
program foo
|
||||
implicit none
|
||||
complex :: cmp(3) = (3.,4.)
|
||||
type ci ! pseudo "complex integer" type
|
||||
integer :: re
|
||||
integer :: im
|
||||
end type ci
|
||||
type cr ! pseudo "complex" type
|
||||
real :: re
|
||||
real :: im
|
||||
end type cr
|
||||
type u
|
||||
type(ci) :: ii(3)
|
||||
type(cr) :: rr(3)
|
||||
end type u
|
||||
type(u) :: cc
|
||||
|
||||
cc% ii% re = nint (cmp% re)
|
||||
cc% ii% im = nint (cmp% im)
|
||||
cc% rr% re = cmp% re
|
||||
cc% rr% im = cmp% im
|
||||
|
||||
call test_substring ()
|
||||
call test_int_real ()
|
||||
call test_poly ()
|
||||
|
||||
contains
|
||||
|
||||
subroutine test_substring ()
|
||||
character(4) :: str(3) = ["abcd","efgh","ijkl"]
|
||||
character(:), allocatable :: ac(:)
|
||||
allocate (ac, source=str(1::2)(2:4))
|
||||
if (size (ac) /= 2 .or. len (ac) /= 3) stop 11
|
||||
if (ac(2) /= "jkl") stop 12
|
||||
deallocate (ac)
|
||||
allocate (ac, mold=str(1::2)(2:4))
|
||||
if (size (ac) /= 2 .or. len (ac) /= 3) stop 13
|
||||
deallocate (ac)
|
||||
end
|
||||
|
||||
subroutine test_int_real ()
|
||||
integer, allocatable :: aa(:)
|
||||
real, pointer :: pp(:)
|
||||
allocate (aa, source = cc% ii% im)
|
||||
if (size (aa) /= 3) stop 21
|
||||
if (any (aa /= cmp% im)) stop 22
|
||||
allocate (pp, source = cc% rr% re)
|
||||
if (size (pp) /= 3) stop 23
|
||||
if (any (pp /= cmp% re)) stop 24
|
||||
deallocate (aa, pp)
|
||||
end
|
||||
|
||||
subroutine test_poly ()
|
||||
class(*), allocatable :: uu(:), vv(:)
|
||||
allocate (uu, source = cc% ii% im)
|
||||
allocate (vv, source = cc% rr% re)
|
||||
if (size (uu) /= 3) stop 31
|
||||
if (size (vv) /= 3) stop 32
|
||||
call check (uu)
|
||||
call check (vv)
|
||||
deallocate (uu, vv)
|
||||
allocate (uu, mold = cc% ii% im)
|
||||
allocate (vv, mold = cc% rr% re)
|
||||
if (size (uu) /= 3) stop 33
|
||||
if (size (vv) /= 3) stop 34
|
||||
deallocate (uu, vv)
|
||||
end
|
||||
|
||||
subroutine check (x)
|
||||
class(*), intent(in) :: x(:)
|
||||
select type (x)
|
||||
type is (integer)
|
||||
if (any (x /= cmp% im)) then
|
||||
print *, "'integer':", x
|
||||
stop 41
|
||||
end if
|
||||
type is (real)
|
||||
if (any (x /= cmp% re)) then
|
||||
print *, "'real':", x
|
||||
stop 42
|
||||
end if
|
||||
type is (character(*))
|
||||
print *, "'character':", x
|
||||
end select
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue