if (gfc_current_state () == COMP_DERIVED
&& !(gfc_state_stack->previous
&& gfc_state_stack->previous->state == COMP_DERIVED)
- && gfc_current_block ()->attr.pdt_template
- && !strcmp (gfc_current_block ()->name, (*sym)->name))
+ && gfc_current_block ()->attr.pdt_template)
{
if (ext_param_list)
*ext_param_list = gfc_copy_actual_arglist (param_list);
type_param_spec_list = old_param_spec_list;
if (!(c2->attr.pointer || c2->attr.allocatable))
- c2->initializer = gfc_default_initializer (&c2->ts);
+ {
+ if (!c1->initializer
+ || c1->initializer->expr_type != EXPR_FUNCTION)
+ c2->initializer = gfc_default_initializer (&c2->ts);
+ else
+ {
+ gfc_symtree *s;
+ c2->initializer = gfc_copy_expr (c1->initializer);
+ s = gfc_find_symtree (pdt->ns->sym_root,
+ gfc_dt_lower_string (c2->ts.u.derived->name));
+ if (s)
+ c2->initializer->symtree = s;
+ c2->initializer->ts = c2->ts;
+ if (!s)
+ gfc_insert_parameter_exprs (c2->initializer,
+ type_param_spec_list);
+ gfc_simplify_expr (params->expr, 1);
+ }
+ }
if (c2->attr.allocatable)
instance->attr.alloc_comp = 1;
symtree->n.sym->ts.type = BT_DERIVED;
}
- /* Append the type_params and the component_values. */
- for (tmp = ctr_arglist; tmp && tmp->next;)
- tmp = tmp->next;
- tmp->next = actual_arglist;
- actual_arglist = ctr_arglist;
+ if (type_spec_list)
+ {
+ /* Append the type_params and the component_values. */
+ for (tmp = ctr_arglist; tmp && tmp->next;)
+ tmp = tmp->next;
+ tmp->next = actual_arglist;
+ actual_arglist = ctr_arglist;
+ tmp = actual_arglist;
+ /* Can now add all the component names. */
+ for (c = pdt_sym->components; c && tmp; c = c->next)
+ {
+ tmp->name = c->name;
+ tmp = tmp->next;
+ }
+ }
}
}
and using trans_assignment to do the work. Set dealloc to false
if no deallocation prior the assignment is needed. */
void
-gfc_init_default_dt (gfc_symbol * sym, stmtblock_t * block, bool dealloc)
+gfc_init_default_dt (gfc_symbol * sym, stmtblock_t * block, bool dealloc,
+ bool pdt_ok)
{
gfc_expr *e;
tree tmp;
gcc_assert (block);
/* Initialization of PDTs is done elsewhere. */
- if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pdt_type)
+ if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pdt_type
+ && !pdt_ok)
return;
gcc_assert (!sym->attr.allocatable);
}
+/* Initialize a PDT, when all the components have an initializer. */
+static void
+gfc_init_default_pdt (gfc_symbol *sym, stmtblock_t *block, bool dealloc)
+{
+ /* Allowed in the case where all the components have initializers and
+ there are no LEN components. */
+ if (sym->ts.type == BT_DERIVED && sym->ts.u.derived->attr.pdt_type)
+ {
+ gfc_component *c = sym->ts.u.derived->components;
+ if (!dealloc || !sym->value || sym->value->expr_type != EXPR_STRUCTURE)
+ return;
+ for (; c; c = c->next)
+ if (c->attr.pdt_len || !c->initializer)
+ return;
+ }
+ else
+ return;
+ gfc_init_default_dt (sym, block, dealloc, true);
+ return;
+}
+
+
/* Initialize INTENT(OUT) derived type dummies. As well as giving
them their default initializer, if they have allocatable
components, they have their allocatable components deallocated. */
gfc_add_expr_to_block (&tmpblock, tmp);
}
+ if (is_pdt_type)
+ gfc_init_default_pdt (sym, &tmpblock, true);
+
if (!sym->attr.result && !sym->ts.u.derived->attr.alloc_comp)
tmp = gfc_deallocate_pdt_comp (sym->ts.u.derived,
sym->backend_decl,
tree gfc_conv_initializer (gfc_expr *, gfc_typespec *, tree, bool, bool, bool);
/* Assign a default initializer to a derived type. */
-void gfc_init_default_dt (gfc_symbol *, stmtblock_t *, bool);
+void gfc_init_default_dt (gfc_symbol *, stmtblock_t *, bool,
+ bool pdt_ok = false);
/* Substitute a temporary variable in place of the real one. */
void gfc_shadow_sym (gfc_symbol *, tree, gfc_saved_var *);
--- /dev/null
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+!
+! Test the second part of the fix for PR103371.
+!
+! Compiled but gave the wrong result for the component 'z%x%n'.
+!
+! Contributed by Arseny Solokha <asolokha@gmx.com>
+!
+module m1
+ implicit none
+ type t
+ integer :: n
+ end type
+ type t2
+ ! t and t2 must be resolved to types in m1, not components in t2
+ type(t) :: t(10) = t(1)
+ type(t) :: x = t(1)
+ integer :: t2
+ type(t2), pointer :: p => NULL()
+ end type
+end
+
+module m2
+ type :: t(tn)
+ integer, kind :: tn
+ integer(kind=tn) :: n
+ end type
+ type :: t2(tm)
+ integer, kind :: tm
+ type(t(tm)) :: x = t(tm)(2*tm)
+ end type
+end
+
+ call test_m2
+contains
+ subroutine test_m2
+ use m2
+ type(t2(KIND (1))) :: z
+ print *, kind (z%x%n), z%x%n
+ end subroutine
+end
+! { dg-final { scan-tree-dump-times "Pdtt2_4.1.x.n = 8" 1 "original" } }
+! { dg-final { scan-tree-dump-times "z = Pdtt2_4.1" 1 "original" } }