diff options
author | Steve Kargl <kargl@gcc.gnu.org> | 2024-02-23 22:05:04 +0100 |
---|---|---|
committer | Harald Anlauf <anlauf@gmx.de> | 2024-02-23 22:34:54 +0100 |
commit | 80d126ba99f4b9bc64d4861b3c4bae666497f2d4 (patch) | |
tree | b6b854c81600366f1af4c5f35260d9f85e8edcb2 /gcc | |
parent | 85c12ae8b80902ed46c97f33dbb61533e07f2905 (diff) | |
download | gcc-80d126ba99f4b9bc64d4861b3c4bae666497f2d4.zip gcc-80d126ba99f4b9bc64d4861b3c4bae666497f2d4.tar.gz gcc-80d126ba99f4b9bc64d4861b3c4bae666497f2d4.tar.bz2 |
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>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/trans-stmt.cc | 10 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/allocate_with_source_27.f90 | 20 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/allocate_with_source_28.f90 | 90 |
3 files changed, 118 insertions, 2 deletions
diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc index 5247d3d..e09828e 100644 --- a/gcc/fortran/trans-stmt.cc +++ b/gcc/fortran/trans-stmt.cc @@ -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) diff --git a/gcc/testsuite/gfortran.dg/allocate_with_source_27.f90 b/gcc/testsuite/gfortran.dg/allocate_with_source_27.f90 new file mode 100644 index 0000000..d0f0f3c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/allocate_with_source_27.f90 @@ -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 + diff --git a/gcc/testsuite/gfortran.dg/allocate_with_source_28.f90 b/gcc/testsuite/gfortran.dg/allocate_with_source_28.f90 new file mode 100644 index 0000000..8548ccb --- /dev/null +++ b/gcc/testsuite/gfortran.dg/allocate_with_source_28.f90 @@ -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 |