This turns out to be obvious. The component of the dummy argument cannot be replaced by the hidden descriptor (actually the class object) and so an ICE occurs. The fix is to add a guard against the expression being a COMPONENT_REF.
I will commit to all three branches tomorrow unless there are any objections. Bootstrapped and regtested on FC29/x86_64 Paul 2019-05-18 Paul Thomas <pa...@gcc.gnu.org> PR fortran/90948 * trans-stmt.c (trans_associate_var) Do not use the saved descriptor if the expression is a COMPONENT_REF. 2019-05-18 Paul Thomas <pa...@gcc.gnu.org> PR fortran/90948 * gfortran.dg/associate_48.f90 : New test.
Index: gcc/fortran/trans-stmt.c =================================================================== *** gcc/fortran/trans-stmt.c (revision 271056) --- gcc/fortran/trans-stmt.c (working copy) *************** trans_associate_var (gfc_symbol *sym, gf *** 1858,1864 **** { if (e->symtree && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl) ! && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl)) /* Use the original class descriptor stored in the saved descriptor to get the target_expr. */ target_expr = --- 1858,1865 ---- { if (e->symtree && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl) ! && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl) ! && TREE_CODE (target_expr) != COMPONENT_REF) /* Use the original class descriptor stored in the saved descriptor to get the target_expr. */ target_expr = Index: gcc/testsuite/gfortran.dg/associate_48.f90 =================================================================== *** gcc/testsuite/gfortran.dg/associate_48.f90 (nonexistent) --- gcc/testsuite/gfortran.dg/associate_48.f90 (working copy) *************** *** 0 **** --- 1,41 ---- + ! { dg=do run } + ! + ! Test the fix for PR90498. + ! + ! Contributed by Vladimir Fuka <vladimir.f...@gmail.com> + ! + type field_names_a + class(*), pointer :: var(:) =>null() + end type + + type(field_names_a),pointer :: a(:) + allocate (a(2)) + + allocate (a(1)%var(2), source = ["hello"," vlad"]) + allocate (a(2)%var(2), source = ["HELLO"," VLAD"]) + call s(a) + deallocate (a(1)%var) + deallocate (a(2)%var) + deallocate (a) + contains + subroutine s(a) + + type(field_names_a) :: a(:) + + select type (var => a(1)%var) + type is (character(*)) + if (any (var .ne. ["hello"," vlad"])) stop 1 + class default + stop + end select + + associate (var => a(2)%var) + select type (var) + type is (character(*)) + if (any (var .ne. ["HELLO"," VLAD"])) stop 2 + class default + stop + end select + end associate + end + end