https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128017
Bug ID: 128017
Summary: ICEs and bogus errors: SELECT TYPE on an ASSOCIATE
name whose selector is a polymorphic function
reference
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: jvdelisle at gcc dot gnu.org
Target Milestone: ---
Reported by Ivan Pribec on Fortran Discourse ("ASSOCIATE bugs").
An ASSOCIATE name bound to a function returning a CLASS pointer array,
then used as a SELECT TYPE selector, fails in several ways. All six
cases below are valid; each should compile and print the value in its
comment. Build one case at a time with -DCASE=n.
CASE 1 associate (a => f()); select type (a); a%re
-> ICE: Segmentation fault
CASE 2 associate (b => g()); select type (b); class is (t); b%c
-> ICE: in gfc_conv_component_ref, at trans-expr.cc
CASE 3 associate (a => (f())); select type (a); a%re
-> Error: Selector in SELECT TYPE at (1) is not a named
variable; use associate-name=>
CASE 4 associate (a => (f())); select type (x => a); x%re
-> ICE: Segmentation fault
CASE 5 associate (b => (g())); select type (b); class is (t); b%c
-> Error: Selector in SELECT TYPE at (1) is not a named
variable; use associate-name=>
CASE 6 associate (b => (g())); select type (x => b); class is (t); x%c
-> Error: Component to the right of a part reference with
nonzero rank must not have the POINTER attribute at (1)
Expected: CASE 1, 3, 4 print " 1.0 3.0"; CASE 2, 5, 6 print " 7 7".
An associate name is a named variable (F2023 11.1.3.3), so the
"not a named variable" error in CASE 3 and 5 is wrong, and no POINTER
component exists for the CASE 6 error to refer to.
CASE 1 crashes in gfc_fixup_inferred_type_refs (resolve.cc), reached
from gfc_match_varspec -> gfc_simplify_expr -> find_inquiry_ref ->
gfc_resolve_expr while the statement is still being parsed. The same
crash occurs for a(2)%im, a%kind, a%len (TYPE IS (CHARACTER(*))) and
for an assignment a(2)%re = 9. It does not occur without the
ASSOCIATE (SELECT TYPE (a => f()) directly), with ASSOCIATE (a => q)
for a CLASS(*) pointer variable q, or without a "%" reference.
CASE 2 compiles with TYPE IS (t) or CLASS DEFAULT instead of
CLASS IS (t), or with SELECT TYPE (b => g()) directly.
! ----- assoc_select_type.F90 -----
module m
implicit none
type :: t
integer :: c = 7
end type
complex, target :: z(2) = [(1., 2.), (3., 4.)]
type(t), target :: dt(2)
contains
function f() result(r)
class(*), pointer :: r(:)
r => z
end function
function g() result(r)
class(t), pointer :: r(:)
r => dt
end function
end module
program p
use m
implicit none
#if CASE == 1
associate (a => f())
select type (a)
type is (complex)
print '(2f5.1)', a%re
end select
end associate
#elif CASE == 2
associate (b => g())
select type (b)
class is (t)
print '(2i3)', b%c
end select
end associate
#elif CASE == 3
associate (a => (f()))
select type (a)
type is (complex)
print '(2f5.1)', a%re
end select
end associate
#elif CASE == 4
associate (a => (f()))
select type (x => a)
type is (complex)
print '(2f5.1)', x%re
end select
end associate
#elif CASE == 5
associate (b => (g()))
select type (b)
class is (t)
print '(2i3)', b%c
end select
end associate
#elif CASE == 6
associate (b => (g()))
select type (x => b)
class is (t)
print '(2i3)', x%c
end select
end associate
#endif
end program