diff options
Diffstat (limited to 'gcc/fortran/expr.cc')
-rw-r--r-- | gcc/fortran/expr.cc | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/gcc/fortran/expr.cc b/gcc/fortran/expr.cc index e418f1f..663fe63 100644 --- a/gcc/fortran/expr.cc +++ b/gcc/fortran/expr.cc @@ -1862,6 +1862,13 @@ find_inquiry_ref (gfc_expr *p, gfc_expr **newp) else if (tmp->expr_type == EXPR_CONSTANT) *newp = gfc_get_int_expr (gfc_default_integer_kind, NULL, tmp->value.character.length); + else if (gfc_init_expr_flag + && tmp->ts.u.cl->length->symtree->n.sym->attr.pdt_len) + *newp = gfc_pdt_find_component_copy_initializer (tmp->symtree->n + .sym, + tmp->ts.u.cl + ->length->symtree + ->n.sym->name); else goto cleanup; @@ -1902,7 +1909,9 @@ find_inquiry_ref (gfc_expr *p, gfc_expr **newp) mpc_imagref (tmp->value.complex), GFC_RND_MODE); break; } - tmp = gfc_copy_expr (*newp); + // TODO: Fix leaking expr tmp, when simplify is done twice. + if (inquiry->next) + gfc_replace_expr (tmp, *newp); } if (!(*newp)) @@ -2067,7 +2076,7 @@ static bool simplify_ref_chain (gfc_ref *ref, int type, gfc_expr **p) { int n; - gfc_expr *newp; + gfc_expr *newp = NULL; for (; ref; ref = ref->next) { @@ -3229,7 +3238,7 @@ gfc_match_init_expr (gfc_expr **result) return m; } - if (gfc_derived_parameter_expr (expr)) + if (expr->expr_type != EXPR_FUNCTION && gfc_derived_parameter_expr (expr)) { *result = expr; gfc_init_expr_flag = false; @@ -6556,3 +6565,19 @@ gfc_check_vardef_context (gfc_expr* e, bool pointer, bool alloc_obj, return true; } + +gfc_expr* +gfc_pdt_find_component_copy_initializer (gfc_symbol *sym, const char *name) +{ + /* The actual length of a pdt is in its components. In the + initializer of the current ref is only the default value. + Therefore traverse the chain of components and pick the correct + one's initializer expressions. */ + for (gfc_component *comp = sym->ts.u.derived->components; comp != NULL; + comp = comp->next) + { + if (!strcmp (comp->name, name)) + return gfc_copy_expr (comp->initializer); + } + return NULL; +} |