Semantically, there is an issue when the function name is used both for
recursively calling and as result variable. Hence, one should only use
one own's function name – in context of function calls – if one has a
separate result variable.
This somehow got messed up with r10-5722-g4d12437 (3 Jan 2020, PR92994)
– rejecting also the use of the function name as result variable.
Fixed by removing the check. At least the most straight-forward invalid
use is still rejected as shown by the augmented test case.
OK for the trunk?
Tobias
On 1/25/20 6:37 AM, Andrew Benson wrote:
I opened PR 93427 for the issue below:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93427
The following code fails to compile (using git commit
472dc648ce3e7661762931d584d239611ddca964):
module a
type :: t
end type t
contains
recursive function b()
class(t), pointer :: b
type(t) :: c
allocate(t :: b)
select type (b)
type is (t)
b=c
end select
end function b
end module a
$ gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/home/abenson/Galacticus/Tools/libexec/gcc/x86_64-pc-linux-gnu/10.0.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-git/configure
--prefix=/home/abenson/Galacticus/Tools
--enable-languages=c,c++,fortran
--disable-multilib
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.0.1 20200124 (experimental) (GCC)
$ gfortran -c p.F90 -o p.o
p.F90:12:15:
12 | select type (b)
| 1
Error: Associating entity 'b' at (1) is a procedure name
p.F90:14:5:
14 | b=c
| 1
Error: 'b' at (1) associated to vector-indexed target cannot be used
in a variable definition context (assignment)
The code compiles successfully using ifort 18.0.1. Removing the
"recursive" attribute, or specifying a "result()" variable makes the
errors go away.
--
* Andrew Benson: http://users.obs.carnegiescience.edu/abenson/contact.html
* Galacticus: https://github.com/galacticusorg/galacticus
[Fortran] Fix to strict associate check (PR93427)
PR fortran/93427
* resolve.c (resolve_assoc_var): Remove too strict check.
* gfortran.dg/associate_51.f90: Update test case.
PR fortran/93427
* gfortran.dg/associate_52.f90: New.
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index e840aec62f2..8f5267fde05 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -8846,8 +8846,7 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target)
if (tsym->attr.subroutine
|| tsym->attr.external
- || (tsym->attr.function
- && (tsym->result != tsym || tsym->attr.recursive)))
+ || (tsym->attr.function && tsym->result != tsym))
{
gfc_error ("Associating entity %qs at %L is a procedure name",
tsym->name, &target->where);
diff --git a/gcc/testsuite/gfortran.dg/associate_51.f90 b/gcc/testsuite/gfortran.dg/associate_51.f90
index 7b3edc44990..b6ab1414b02 100644
--- a/gcc/testsuite/gfortran.dg/associate_51.f90
+++ b/gcc/testsuite/gfortran.dg/associate_51.f90
@@ -14,7 +14,14 @@ end
recursive function f2()
associate (y1 => f2()) ! { dg-error "Invalid association target" }
end associate ! { dg-error "Expecting END FUNCTION statement" }
- associate (y2 => f2) ! { dg-error "is a procedure name" }
+end
+
+recursive function f3()
+ associate (y1 => f3)
+ print *, y1() ! { dg-error "Expected array subscript" }
+ end associate
+ associate (y2 => f3) ! { dg-error "Associate-name 'y2' at \\(1\\) is used as array" }
+ print *, y2(1)
end associate
end
diff --git a/gcc/testsuite/gfortran.dg/associate_52.f90 b/gcc/testsuite/gfortran.dg/associate_52.f90
new file mode 100644
index 00000000000..c24ec4b8f6a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/associate_52.f90
@@ -0,0 +1,24 @@
+! { dg-do compile }
+!
+! PR fortran/93427
+!
+! Contributed by Andrew Benson
+!
+module a
+
+type :: t
+end type t
+
+contains
+
+recursive function b()
+ class(t), pointer :: b
+ type(t) :: c
+ allocate(t :: b)
+ select type (b)
+ type is (t)
+ b=c
+ end select
+end function b
+
+end module a