diff options
author | Mikael Morin <mikael@gcc.gnu.org> | 2022-04-27 11:36:00 +0200 |
---|---|---|
committer | Mikael Morin <mikael@gcc.gnu.org> | 2022-04-27 11:36:00 +0200 |
commit | 3e0c9fdfd00b5b5cbff1a0bd6ac012a10fe81348 (patch) | |
tree | 9c5c72bdd1fdaf721c031867da9674962a8c5f1d | |
parent | 6c211e70eb9d89db2be630c0d5555d21e4aee144 (diff) | |
download | gcc-3e0c9fdfd00b5b5cbff1a0bd6ac012a10fe81348.zip gcc-3e0c9fdfd00b5b5cbff1a0bd6ac012a10fe81348.tar.gz gcc-3e0c9fdfd00b5b5cbff1a0bd6ac012a10fe81348.tar.bz2 |
fortran: Avoid infinite self-recursion [PR105381]
Dummy array decls are local decls different from the argument decl
accessible through GFC_DECL_SAVED_DESCRIPTOR. If the argument decl has
a DECL_LANG_SPECIFIC set, it is copied over to the local decl at the
time the latter is created, so that the DECL_LANG_SPECIFIC object is
shared between local dummy decl and argument decl, and thus the
GFC_DECL_SAVED_DESCRIPTOR of the argument decl is the argument decl
itself.
The r12-8230-g7964ab6c364c410c34efe7ca2eba797d36525349 change introduced
the non_negative_strides_array_p predicate which recurses through
GFC_DECL_SAVED_DESCRIPTOR to avoid seeing dummy decls as purely local
decls. As the GFC_DECL_SAVED_DESCRIPTOR of the argument decl is itself,
this can cause infinite recursion.
This change adds a check to avoid infinite recursion.
PR fortran/102043
PR fortran/105381
gcc/fortran/ChangeLog:
* trans-array.cc (non_negative_strides_array_p): Inline variable
orig_decl and merge nested if conditions. Add condition to not
recurse if the next argument is the same as the current.
gcc/testsuite/ChangeLog:
* gfortran.dg/character_array_dummy_1.f90: New test.
-rw-r--r-- | gcc/fortran/trans-array.cc | 7 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/character_array_dummy_1.f90 | 21 |
2 files changed, 25 insertions, 3 deletions
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index e4b6270..0513495 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -3696,9 +3696,10 @@ non_negative_strides_array_p (tree expr) /* If the array was originally a dummy with a descriptor, strides can be negative. */ if (DECL_P (expr) - && DECL_LANG_SPECIFIC (expr)) - if (tree orig_decl = GFC_DECL_SAVED_DESCRIPTOR (expr)) - return non_negative_strides_array_p (orig_decl); + && DECL_LANG_SPECIFIC (expr) + && GFC_DECL_SAVED_DESCRIPTOR (expr) + && GFC_DECL_SAVED_DESCRIPTOR (expr) != expr) + return non_negative_strides_array_p (GFC_DECL_SAVED_DESCRIPTOR (expr)); return true; } diff --git a/gcc/testsuite/gfortran.dg/character_array_dummy_1.f90 b/gcc/testsuite/gfortran.dg/character_array_dummy_1.f90 new file mode 100644 index 0000000..da5ed63 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/character_array_dummy_1.f90 @@ -0,0 +1,21 @@ +! { dg-do compile } +! +! PR fortran/105381 +! Infinite recursion with array references of character dummy arguments. +! +! Contributed by Harald Anlauf <anlauf@gmx.de> + +MODULE m + implicit none + integer, parameter :: ncrit = 8 + integer, parameter :: nterm = 7 +contains + + subroutine new_thin_rule (rule1) + character(*),intent(in) ,optional :: rule1(ncrit) + character(len=8) :: rules (ncrit,nterm) + rules = '' + if (present (rule1)) rules(:,1) = rule1 ! <-- compile time hog + end subroutine new_thin_rule + +end module m |