Re: [Patch, fortran PR89645/99065 No IMPLICIT type error with: ASSOCIATE( X => function() )

2024-03-12 Thread Paul Richard Thomas
Hi Harald,

Roger that about the comments. The major part of my recent efforts has been
to maximise comments - apparently not always successfully!

The main reason that I want to "fix everything" is that this is it; I will
not work on this approach anymore. The gfortran/g95 founder's approach was
very clever but has found it's limit with the associate construct. The sad
thing is that this is the only blocker that I know of.

Thanks

Paul


On Tue, 12 Mar 2024 at 21:07, Harald Anlauf  wrote:

> Hi Paul,
>
> On 3/12/24 15:54, Paul Richard Thomas wrote:
> > Hi All,
> >
> > This is the last posting of this patch before I push it. Harald is OK
> with
> > it on the grounds that the inferred_type flag guards the whole lot,
> > except for the chunks in trans-stmt.cc.
> >
> > In spite of Harald's off-list admonition not to try to fix everything at
> > once, this version fixes most of the inquiry reference bugs
> > (associate_68.f90) with the exception of character(kind=4) function
> > selectors. The reason for this is that I have some housekeeping to do
> > before release on finalization and then I want to replace this patch in
> > 15-branch with two pass parsing. My first attempts at the latter were a
> > partial success.
>
> you wouldn't stop trying to fix everything, would you?  ;-)
>
> > It regtests OK on x86_64. Unless there are objections, I will commit on
> > Thursday evening.
>
> No objections, just one wish: could you improve the text of the
> following comments so that mere mortals understand them?
>
> diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
> index 12e7bf3c873..0ab69bb9dce 100644
> --- a/gcc/fortran/primary.cc
> +++ b/gcc/fortran/primary.cc
> [...]
> +  /* If there is a usable inquiry reference not there are no matching
> +derived types, force the inquiry reference by setting unknown the
> +type of the primary expression.  */
>
>
> I have a hard time parsing the first part of that sentence.
>
> diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc
> index 5d9852c79e0..16adb2a7efb 100644
> --- a/gcc/fortran/symbol.cc
> +++ b/gcc/fortran/symbol.cc
> [...]
> +/* Find all derived types in the uppermost namespace that have a component
> +   a component called name and stash them in the assoc field of an
> +   associate name variable.
>
>
> "a component" too much?
>
> Thanks,
> Harald
>
> > Cheers
> >
> > Paul
>
>


Re: [Patch, fortran PR89645/99065 No IMPLICIT type error with: ASSOCIATE( X => function() )

2024-03-12 Thread Harald Anlauf

Hi Paul,

On 3/12/24 15:54, Paul Richard Thomas wrote:

Hi All,

This is the last posting of this patch before I push it. Harald is OK with
it on the grounds that the inferred_type flag guards the whole lot,
except for the chunks in trans-stmt.cc.

In spite of Harald's off-list admonition not to try to fix everything at
once, this version fixes most of the inquiry reference bugs
(associate_68.f90) with the exception of character(kind=4) function
selectors. The reason for this is that I have some housekeeping to do
before release on finalization and then I want to replace this patch in
15-branch with two pass parsing. My first attempts at the latter were a
partial success.


you wouldn't stop trying to fix everything, would you?  ;-)


It regtests OK on x86_64. Unless there are objections, I will commit on
Thursday evening.


No objections, just one wish: could you improve the text of the
following comments so that mere mortals understand them?

diff --git a/gcc/fortran/primary.cc b/gcc/fortran/primary.cc
index 12e7bf3c873..0ab69bb9dce 100644
--- a/gcc/fortran/primary.cc
+++ b/gcc/fortran/primary.cc
[...]
+  /* If there is a usable inquiry reference not there are no matching
+derived types, force the inquiry reference by setting unknown the
+type of the primary expression.  */


I have a hard time parsing the first part of that sentence.

diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc
index 5d9852c79e0..16adb2a7efb 100644
--- a/gcc/fortran/symbol.cc
+++ b/gcc/fortran/symbol.cc
[...]
+/* Find all derived types in the uppermost namespace that have a component
+   a component called name and stash them in the assoc field of an
+   associate name variable.


"a component" too much?

Thanks,
Harald


Cheers

Paul





Re: [Patch, fortran PR89645/99065 No IMPLICIT type error with: ASSOCIATE( X => function() )

2024-03-12 Thread Paul Richard Thomas
Hi All,

This is the last posting of this patch before I push it. Harald is OK with
it on the grounds that the inferred_type flag guards the whole lot,
except for the chunks in trans-stmt.cc.

In spite of Harald's off-list admonition not to try to fix everything at
once, this version fixes most of the inquiry reference bugs
(associate_68.f90) with the exception of character(kind=4) function
selectors. The reason for this is that I have some housekeeping to do
before release on finalization and then I want to replace this patch in
15-branch with two pass parsing. My first attempts at the latter were a
partial success.

It regtests OK on x86_64. Unless there are objections, I will commit on
Thursday evening.

Cheers

Paul

Fortran: Fix class/derived/complex function associate selectors [PR87477]

2024-03-12  Paul Thomas  

gcc/fortran
PR fortran/87477
PR fortran/89645
PR fortran/99065
PR fortran/114141
PR fortran/114280
* class.cc (gfc_change_class): New function needed for
associate names, when rank changes or a derived type is
produced by resolution
* dump-parse-tree.cc (show_code_node): Make output for SELECT
TYPE more comprehensible.
* expr.cc (find_inquiry_ref): Do not simplify expressions of
an inferred type.
* gfortran.h : Add 'gfc_association_list' to structure
'gfc_association_list'. Add prototypes for
'gfc_find_derived_types', 'gfc_fixup_inferred_type_refs' and
'gfc_change_class'. Add macro IS_INFERRED_TYPE.
* match.cc (copy_ts_from_selector_to_associate): Add bolean arg
'select_type' with default false. If this is a select type name
and the selector is a inferred type, build the class type and
apply it to the associate name.
(build_associate_name): Pass true to 'select_type' in call to
previous.
* parse.cc (parse_associate): If the selector is inferred type
the associate name is too. Make sure that function selector
class and rank, if known, are passed to the associate name. If
a function result exists, pass its typespec to the associate
name.
* primary.cc (resolvable_fcns): New function to check that all
the function references are resolvable.
(gfc_match_varspec): If a scalar derived type select type
temporary has an array reference, match the array reference,
treating this in the same way as an equivalence member. Do not
set 'inquiry' if applied to an unknown type the inquiry name
is ambiguous with the component of an accessible derived type.
Check that resolution of the target expression is OK by testing
if the symbol is declared or is an operator expression, then
using 'resolvable_fcns' recursively. If all is well, resolve
the expression. If this is an inferred type with a component
reference, call 'gfc_find_derived_types' to find a suitable
derived type. If there is an inquiry ref and the symbol either
is of unknown type or is inferred to be a derived type, set the
primary and symbol TKR appropriately.
* resolve.cc (resolve_variable): Call new function below.
(gfc_fixup_inferred_type_refs): New function to ensure that the
expression references for a inferred type are consistent with
the now fixed up selector.
(resolve_assoc_var): Ensure that derived type or class function
selectors transmit the correct arrayspec to the associate name.
(resolve_select_type): If the selector is an associate name of
inferred type and has no component references, the associate
name should have its typespec. Simplify the conversion of a
class array to class scalar by calling 'gfc_change_class'.
Make sure that a class, inferred type selector with an array
ref transfers the typespec from the symbol to the expression.
* symbol.cc (gfc_set_default_type): If an associate name with
unknown type has a selector expression, try resolving the expr.
(find_derived_types, gfc_find_derived_types): New functions
that search for a derived type with a given name.
* trans-expr.cc (gfc_conv_variable): Some inferred type exprs
escape resolution so call 'gfc_fixup_inferred_type_refs'.
* trans-stmt.cc (trans_associate_var): Tidy up expression for
'class_target'. Finalize and free class function results.
Correctly handle selectors that are class functions and class
array references, passed as derived types.

gcc/testsuite/
PR fortran/87477
PR fortran/89645
PR fortran/99065
* gfortran.dg/associate_64.f90 : New test
* gfortran.dg/associate_66.f90 : New test
* gfortran.dg/associate_67.f90 : New test

PR fortran/114141
* gfortran.dg/associate_65.f90 : New test

PR fortran/114280
* gfortran.dg/associate_68.f90 : New test
diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index ce31a93abcd..abe89630be3 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -815,6 +815,56 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
 }
 
 
+/* Change class, using gfc_build_class_symbol. This is needed for associate
+   names, when rank changes or a derived type is produced by resolution.  */
+
+void
+gfc_change_class (gfc_typespec *ts, symbol_attribute *sym_attr,
+		  gfc_array_spec *sym_as, int rank, int corank)
+{
+  

Re: [Patch, fortran PR89645/99065 No IMPLICIT type error with: ASSOCIATE( X => function() )

2024-03-03 Thread Harald Anlauf

Hi Paul,

welcome back!

On 3/3/24 17:04, Paul Richard Thomas wrote:

Hi Harald,

Please find an updated version of the patch that rolls in Steve's patch for
PR114141, fixes unlimited polymorphic function selectors and cures the
memory leaks. I apologise for not working on this sooner but, as I informed
you, I have been away for an extended trip to Australia.

The chunks that fix PR114141 are picked out in comment 14 to the PR and the
cures to the problems that you found in the first review are found at
trans-stmt.cc:2047-49.

Regtests fine. OK for trunk, bearing in mind that most of the patch is ring
fenced by the inferred_type flag?


I would say that it is almost fine.

Two things that I found:

- Testcase associate_65.f90 does not compile with -std=f2023, because
  IMAG is a GNU extension, while AIMAG is the standard version.
  Could you please adjust that?

- I think the handling of parentheses and functions returning pointers
  does not work correctly.  Consider:


program paul
  implicit none
  type t
 integer :: i
  end type t
  type(t), pointer :: p(:)
  allocate (p(-3:3))

  associate (q => p)
print *, lbound (q), ubound (q) ! Should print -3 3 (OK)
  end associate

  associate (q => set_ptr())
print *, lbound (q), ubound (q) ! Should print -3 3 (OK)
  end associate

  associate (q => (p))
print *, lbound (q), ubound (q) ! Should print 1 7 (OK)
  end associate

  associate (q => (set_ptr()))  ! <- are these parentheses lost?
print *, lbound (q), ubound (q) ! Should print 1 7
  end associate
contains
  function set_ptr () result (res)
type(t), pointer :: res(:)
res => p
  end function set_ptr
end


While the first three variants give the right bounds, the last version
- after applying your patch - is mishandled and the testcase now prints:

  -3   3
  -3   3
   1   7
  -3   3

Both NAG and Intel support my expectation, namely that the last line
should equal the next-to-last.

Can you recheck the logic for that particular corner case?

With these points addressed, your patch is OK from my side.

Thanks for the patch and your endurance!

Harald



Cheers

Paul


On Mon, 8 Jan 2024 at 21:53, Harald Anlauf  wrote:


Hi Paul,

your patch looks already very impressive!

Regarding the patch as is, I am still trying to grok it, even with your
explanations at hand...

While the testcase works as advertised, I noticed that it exhibits a
runtime memleak that occurs for (likely) each case where the associate
target is an allocatable, class-valued function result.

I tried to produce a minimal testcase using class(*), which apparently
is not handled by your patch (it ICEs for me):

program p
implicit none
class(*), allocatable :: x(:)
x = foo()
call prt (x)
deallocate (x)
! up to here no memleak...
associate (var => foo())
  call prt (var)
end associate
contains
function foo() result(res)
  class(*), allocatable :: res(:)
  res = [42]
end function foo
subroutine prt (x)
  class(*), intent(in) :: x(:)
  select type (x)
  type is (integer)
 print *, x
  class default
 stop 99
  end select
end subroutine prt
end

Traceback (truncated):

foo.f90:9:18:

  9 | call prt (var)
|  1
internal compiler error: tree check: expected record_type or union_type
or qual_union_type, have function_type in gfc_class_len_get, at
fortran/trans-expr.cc:271
0x19fd5d5 tree_check_failed(tree_node const*, char const*, int, char
const*, ...)
  ../../gcc-trunk/gcc/tree.cc:8952
0xe1562d tree_check3(tree_node*, char const*, int, char const*,
tree_code, tree_code, tree_code)
  ../../gcc-trunk/gcc/tree.h:3652
0xe3e264 gfc_class_len_get(tree_node*)
  ../../gcc-trunk/gcc/fortran/trans-expr.cc:271
0xecda48 trans_associate_var
  ../../gcc-trunk/gcc/fortran/trans-stmt.cc:2325
0xecdd09 gfc_trans_block_construct(gfc_code*)
  ../../gcc-trunk/gcc/fortran/trans-stmt.cc:2383
[...]

I don't see anything wrong with it: NAG groks it, like Nvidia and Flang,
while Intel crashes at runtime.

Can you have another brief look?

Thanks,
Harald


On 1/6/24 18:26, Paul Richard Thomas wrote:

These PRs come about because of gfortran's single pass parsing. If the
function in the title is parsed after the associate construct, then its
type and rank are not known. The point at which this becomes a problem is
when expressions within the associate block are parsed. primary.cc
(gfc_match_varspec) could already deal with intrinsic types and so
component references were the trigger for the problem.

The two major parts of this patch are the fixup needed in

gfc_match_varspec

and the resolution of  expressions with references in resolve.cc
(gfc_fixup_inferred_type_refs). The former relies on the two new

functions

in symbol.cc to search for derived types with an appropriate component to
match the component 

Re: [Patch, fortran PR89645/99065 No IMPLICIT type error with: ASSOCIATE( X => function() )

2024-03-03 Thread Paul Richard Thomas
Hi Harald,

Please find an updated version of the patch that rolls in Steve's patch for
PR114141, fixes unlimited polymorphic function selectors and cures the
memory leaks. I apologise for not working on this sooner but, as I informed
you, I have been away for an extended trip to Australia.

The chunks that fix PR114141 are picked out in comment 14 to the PR and the
cures to the problems that you found in the first review are found at
trans-stmt.cc:2047-49.

Regtests fine. OK for trunk, bearing in mind that most of the patch is ring
fenced by the inferred_type flag?

Cheers

Paul


On Mon, 8 Jan 2024 at 21:53, Harald Anlauf  wrote:

> Hi Paul,
>
> your patch looks already very impressive!
>
> Regarding the patch as is, I am still trying to grok it, even with your
> explanations at hand...
>
> While the testcase works as advertised, I noticed that it exhibits a
> runtime memleak that occurs for (likely) each case where the associate
> target is an allocatable, class-valued function result.
>
> I tried to produce a minimal testcase using class(*), which apparently
> is not handled by your patch (it ICEs for me):
>
> program p
>implicit none
>class(*), allocatable :: x(:)
>x = foo()
>call prt (x)
>deallocate (x)
>! up to here no memleak...
>associate (var => foo())
>  call prt (var)
>end associate
> contains
>function foo() result(res)
>  class(*), allocatable :: res(:)
>  res = [42]
>end function foo
>subroutine prt (x)
>  class(*), intent(in) :: x(:)
>  select type (x)
>  type is (integer)
> print *, x
>  class default
> stop 99
>  end select
>end subroutine prt
> end
>
> Traceback (truncated):
>
> foo.f90:9:18:
>
>  9 | call prt (var)
>|  1
> internal compiler error: tree check: expected record_type or union_type
> or qual_union_type, have function_type in gfc_class_len_get, at
> fortran/trans-expr.cc:271
> 0x19fd5d5 tree_check_failed(tree_node const*, char const*, int, char
> const*, ...)
>  ../../gcc-trunk/gcc/tree.cc:8952
> 0xe1562d tree_check3(tree_node*, char const*, int, char const*,
> tree_code, tree_code, tree_code)
>  ../../gcc-trunk/gcc/tree.h:3652
> 0xe3e264 gfc_class_len_get(tree_node*)
>  ../../gcc-trunk/gcc/fortran/trans-expr.cc:271
> 0xecda48 trans_associate_var
>  ../../gcc-trunk/gcc/fortran/trans-stmt.cc:2325
> 0xecdd09 gfc_trans_block_construct(gfc_code*)
>  ../../gcc-trunk/gcc/fortran/trans-stmt.cc:2383
> [...]
>
> I don't see anything wrong with it: NAG groks it, like Nvidia and Flang,
> while Intel crashes at runtime.
>
> Can you have another brief look?
>
> Thanks,
> Harald
>
>
> On 1/6/24 18:26, Paul Richard Thomas wrote:
> > These PRs come about because of gfortran's single pass parsing. If the
> > function in the title is parsed after the associate construct, then its
> > type and rank are not known. The point at which this becomes a problem is
> > when expressions within the associate block are parsed. primary.cc
> > (gfc_match_varspec) could already deal with intrinsic types and so
> > component references were the trigger for the problem.
> >
> > The two major parts of this patch are the fixup needed in
> gfc_match_varspec
> > and the resolution of  expressions with references in resolve.cc
> > (gfc_fixup_inferred_type_refs). The former relies on the two new
> functions
> > in symbol.cc to search for derived types with an appropriate component to
> > match the component reference and then set the associate name to have a
> > matching derived type. gfc_fixup_inferred_type_refs is called in
> resolution
> > and so the type of the selector function is known.
> > gfc_fixup_inferred_type_refs ensures that the component references use
> this
> > derived type and that array references occur in the right place in
> > expressions and match preceding array specs. Most of the work in
> preparing
> > the patch was sorting out cases where the selector was not a derived type
> > but, instead, a class function. If it were not for this, the patch would
> > have been submitted six months ago :-(
> >
> > The patch is relatively safe because most of the chunks are guarded by
> > testing for the associate name being an inferred type, which is set in
> > gfc_match_varspec. For this reason, I do not think it likely that the
> patch
> > will cause regressions. However, it is more than possible that variants
> not
> > appearing in the submitted testcase will throw up new bugs.
> >
> > Jerry has already given the patch a whirl and found that it applies
> > cleanly, regtests OK and works as advertised.
> >
> > OK for trunk?
> >
> > Paul
> ...snip...
diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index ce31a93abcd..abe89630be3 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -815,6 +815,56 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
 }
 
 
+/* Change class, using gfc_build_class_symbol. 

Re: [Patch, fortran PR89645/99065 No IMPLICIT type error with: ASSOCIATE( X => function() )

2024-01-08 Thread Harald Anlauf

Hi Paul,

your patch looks already very impressive!

Regarding the patch as is, I am still trying to grok it, even with your
explanations at hand...

While the testcase works as advertised, I noticed that it exhibits a
runtime memleak that occurs for (likely) each case where the associate
target is an allocatable, class-valued function result.

I tried to produce a minimal testcase using class(*), which apparently
is not handled by your patch (it ICEs for me):

program p
  implicit none
  class(*), allocatable :: x(:)
  x = foo()
  call prt (x)
  deallocate (x)
  ! up to here no memleak...
  associate (var => foo())
call prt (var)
  end associate
contains
  function foo() result(res)
class(*), allocatable :: res(:)
res = [42]
  end function foo
  subroutine prt (x)
class(*), intent(in) :: x(:)
select type (x)
type is (integer)
   print *, x
class default
   stop 99
end select
  end subroutine prt
end

Traceback (truncated):

foo.f90:9:18:

9 | call prt (var)
  |  1
internal compiler error: tree check: expected record_type or union_type
or qual_union_type, have function_type in gfc_class_len_get, at
fortran/trans-expr.cc:271
0x19fd5d5 tree_check_failed(tree_node const*, char const*, int, char
const*, ...)
../../gcc-trunk/gcc/tree.cc:8952
0xe1562d tree_check3(tree_node*, char const*, int, char const*,
tree_code, tree_code, tree_code)
../../gcc-trunk/gcc/tree.h:3652
0xe3e264 gfc_class_len_get(tree_node*)
../../gcc-trunk/gcc/fortran/trans-expr.cc:271
0xecda48 trans_associate_var
../../gcc-trunk/gcc/fortran/trans-stmt.cc:2325
0xecdd09 gfc_trans_block_construct(gfc_code*)
../../gcc-trunk/gcc/fortran/trans-stmt.cc:2383
[...]

I don't see anything wrong with it: NAG groks it, like Nvidia and Flang,
while Intel crashes at runtime.

Can you have another brief look?

Thanks,
Harald


On 1/6/24 18:26, Paul Richard Thomas wrote:

These PRs come about because of gfortran's single pass parsing. If the
function in the title is parsed after the associate construct, then its
type and rank are not known. The point at which this becomes a problem is
when expressions within the associate block are parsed. primary.cc
(gfc_match_varspec) could already deal with intrinsic types and so
component references were the trigger for the problem.

The two major parts of this patch are the fixup needed in gfc_match_varspec
and the resolution of  expressions with references in resolve.cc
(gfc_fixup_inferred_type_refs). The former relies on the two new functions
in symbol.cc to search for derived types with an appropriate component to
match the component reference and then set the associate name to have a
matching derived type. gfc_fixup_inferred_type_refs is called in resolution
and so the type of the selector function is known.
gfc_fixup_inferred_type_refs ensures that the component references use this
derived type and that array references occur in the right place in
expressions and match preceding array specs. Most of the work in preparing
the patch was sorting out cases where the selector was not a derived type
but, instead, a class function. If it were not for this, the patch would
have been submitted six months ago :-(

The patch is relatively safe because most of the chunks are guarded by
testing for the associate name being an inferred type, which is set in
gfc_match_varspec. For this reason, I do not think it likely that the patch
will cause regressions. However, it is more than possible that variants not
appearing in the submitted testcase will throw up new bugs.

Jerry has already given the patch a whirl and found that it applies
cleanly, regtests OK and works as advertised.

OK for trunk?

Paul

Fortran: Fix class/derived type function associate selectors [PR87477]

2024-01-06  Paul Thomas  

gcc/fortran
PR fortran/87477
PR fortran/89645
PR fortran/99065
* class.cc (gfc_change_class): New function needed for
associate names, when rank changes or a derived type is
produced by resolution
* dump-parse-tree.cc (show_code_node): Make output for SELECT
TYPE more comprehensible.
* gfortran.h : Add 'gfc_association_list' to structure
'gfc_association_list'. Add prototypes for
'gfc_find_derived_types', 'gfc_fixup_inferred_type_refs' and
'gfc_change_class'. Add macro IS_INFERRED_TYPE.
* match.cc (copy_ts_from_selector_to_associate): Add bolean arg
'select_type' with default false. If this is a select type name
and the selector is a inferred type, build the class type and
apply it to the associate name.
(build_associate_name): Pass true to 'select_type' in call to
previous.
* parse.cc (parse_associate): If the selector is a inferred type
the associate name is too. Make sure that function selector
class and rank, if known, are passed to the associate name. If
a function result exists, pass its typespec to the associate
name.
* primary.cc (gfc_match_varspec): If a scalar derived type
select type temporary has an array reference, 

[Patch, fortran PR89645/99065 No IMPLICIT type error with: ASSOCIATE( X => function() )

2024-01-06 Thread Paul Richard Thomas
These PRs come about because of gfortran's single pass parsing. If the
function in the title is parsed after the associate construct, then its
type and rank are not known. The point at which this becomes a problem is
when expressions within the associate block are parsed. primary.cc
(gfc_match_varspec) could already deal with intrinsic types and so
component references were the trigger for the problem.

The two major parts of this patch are the fixup needed in gfc_match_varspec
and the resolution of  expressions with references in resolve.cc
(gfc_fixup_inferred_type_refs). The former relies on the two new functions
in symbol.cc to search for derived types with an appropriate component to
match the component reference and then set the associate name to have a
matching derived type. gfc_fixup_inferred_type_refs is called in resolution
and so the type of the selector function is known.
gfc_fixup_inferred_type_refs ensures that the component references use this
derived type and that array references occur in the right place in
expressions and match preceding array specs. Most of the work in preparing
the patch was sorting out cases where the selector was not a derived type
but, instead, a class function. If it were not for this, the patch would
have been submitted six months ago :-(

The patch is relatively safe because most of the chunks are guarded by
testing for the associate name being an inferred type, which is set in
gfc_match_varspec. For this reason, I do not think it likely that the patch
will cause regressions. However, it is more than possible that variants not
appearing in the submitted testcase will throw up new bugs.

Jerry has already given the patch a whirl and found that it applies
cleanly, regtests OK and works as advertised.

OK for trunk?

Paul

Fortran: Fix class/derived type function associate selectors [PR87477]

2024-01-06  Paul Thomas  

gcc/fortran
PR fortran/87477
PR fortran/89645
PR fortran/99065
* class.cc (gfc_change_class): New function needed for
associate names, when rank changes or a derived type is
produced by resolution
* dump-parse-tree.cc (show_code_node): Make output for SELECT
TYPE more comprehensible.
* gfortran.h : Add 'gfc_association_list' to structure
'gfc_association_list'. Add prototypes for
'gfc_find_derived_types', 'gfc_fixup_inferred_type_refs' and
'gfc_change_class'. Add macro IS_INFERRED_TYPE.
* match.cc (copy_ts_from_selector_to_associate): Add bolean arg
'select_type' with default false. If this is a select type name
and the selector is a inferred type, build the class type and
apply it to the associate name.
(build_associate_name): Pass true to 'select_type' in call to
previous.
* parse.cc (parse_associate): If the selector is a inferred type
the associate name is too. Make sure that function selector
class and rank, if known, are passed to the associate name. If
a function result exists, pass its typespec to the associate
name.
* primary.cc (gfc_match_varspec): If a scalar derived type
select type temporary has an array reference, match the array
reference, treating this in the same way as an equivalence
member. If this is a inferred type with a component reference,
call 'gfc_find_derived_types' to find a suitable derived type.
* resolve.cc (resolve_variable): Call new function below.
(gfc_fixup_inferred_type_refs): New function to ensure that the
expression references for a inferred type are consistent with
the now fixed up selector.
(resolve_assoc_var): Ensure that derived type or class function
selectors transmit the correct arrayspec to the associate name.
(resolve_select_type): If the selector is an associate name of
inferred type and has no component references, the associate
name should have its typespec.
* symbol.cc (gfc_set_default_type): If an associate name with
unknown type has a selector expression, try resolving the expr.
(find_derived_types, gfc_find_derived_types): New functions
that search for a derived type with a given name.
* trans-expr.cc (gfc_conv_variable): Some inferred type exprs
escape resolution so call 'gfc_fixup_inferred_type_refs'.
* trans-stmt.cc (trans_associate_var): Tidy up expression for
'class_target'. Correctly handle selectors that are class array
references, passed as derived types.

gcc/testsuite/
PR fortran/87477
PR fortran/89645
PR fortran/99065
* gfortran.dg/associate_64.f90 : New test
diff --git a/gcc/fortran/class.cc b/gcc/fortran/class.cc
index 5c43b77dba3..7db1ecbd264 100644
--- a/gcc/fortran/class.cc
+++ b/gcc/fortran/class.cc
@@ -815,6 +815,56 @@ gfc_build_class_symbol (gfc_typespec *ts, symbol_attribute *attr,
 }
 
 
+/* Change class, using gfc_build_class_symbol. This is needed for associate
+   names, when rank changes or a derived type is produced by resolution.  */
+
+void
+gfc_change_class (gfc_typespec *ts, symbol_attribute *sym_attr,
+		  gfc_array_spec *sym_as, int rank, int corank)
+{
+  symbol_attribute attr;
+  gfc_component *c;
+  gfc_array_spec *as = NULL;
+  gfc_symbol *der = ts->u.derived;