diff options
author | Janus Weil <janus@gcc.gnu.org> | 2012-11-26 11:30:12 +0100 |
---|---|---|
committer | Janus Weil <janus@gcc.gnu.org> | 2012-11-26 11:30:12 +0100 |
commit | fca04db3357621cd2e2d09a6836966b485b34f90 (patch) | |
tree | c3fa52f3edc064336f829a705cf3c03187698ac2 /gcc/fortran/match.c | |
parent | 412dc8423772fb83da7c616900db8a66b84e1f2b (diff) | |
download | gcc-fca04db3357621cd2e2d09a6836966b485b34f90.tar.gz |
re PR fortran/54881 ([OOP] ICE in fold_convert_loc, at fold-const.c:2016)
2012-11-26 Janus Weil <janus@gcc.gnu.org>
PR fortran/54881
* match.c (select_derived_set_tmp,select_class_set_tmp): Removed and
unified into ...
(select_type_set_tmp): ... this one. Set POINTER argument according to
selector.
* trans-intrinsic.c (gfc_conv_associated): Use 'gfc_class_data_get'
instead of 'gfc_add_data_component'.
2012-11-26 Janus Weil <janus@gcc.gnu.org>
PR fortran/54881
* gfortran.dg/associated_6.f90: New.
* gfortran.dg/select_type_30.f03: New.
From-SVN: r193809
Diffstat (limited to 'gcc/fortran/match.c')
-rw-r--r-- | gcc/fortran/match.c | 105 |
1 files changed, 29 insertions, 76 deletions
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index 06585af94e9..39da62faedf 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -5207,103 +5207,56 @@ select_type_push (gfc_symbol *sel) } -/* Set the temporary for the current derived type SELECT TYPE selector. */ +/* Set up a temporary for the current TYPE IS / CLASS IS branch . */ -static gfc_symtree * -select_derived_set_tmp (gfc_typespec *ts) +static void +select_type_set_tmp (gfc_typespec *ts) { char name[GFC_MAX_SYMBOL_LEN]; gfc_symtree *tmp; - - sprintf (name, "__tmp_type_%s", ts->u.derived->name); - gfc_get_sym_tree (name, gfc_current_ns, &tmp, false); - gfc_add_type (tmp->n.sym, ts, NULL); - /* Copy across the array spec to the selector. */ - if (select_type_stack->selector->ts.type == BT_CLASS - && select_type_stack->selector->attr.class_ok - && (CLASS_DATA (select_type_stack->selector)->attr.dimension - || CLASS_DATA (select_type_stack->selector)->attr.codimension)) + if (!ts) { - tmp->n.sym->attr.dimension - = CLASS_DATA (select_type_stack->selector)->attr.dimension; - tmp->n.sym->attr.codimension - = CLASS_DATA (select_type_stack->selector)->attr.codimension; - tmp->n.sym->as - = gfc_copy_array_spec (CLASS_DATA (select_type_stack->selector)->as); + select_type_stack->tmp = NULL; + return; } - - gfc_set_sym_referenced (tmp->n.sym); - gfc_add_flavor (&tmp->n.sym->attr, FL_VARIABLE, name, NULL); - tmp->n.sym->attr.select_type_temporary = 1; - - return tmp; -} - - -/* Set the temporary for the current class SELECT TYPE selector. */ - -static gfc_symtree * -select_class_set_tmp (gfc_typespec *ts) -{ - char name[GFC_MAX_SYMBOL_LEN]; - gfc_symtree *tmp; - if (select_type_stack->selector->ts.type == BT_CLASS - && !select_type_stack->selector->attr.class_ok) - return NULL; + if (!gfc_type_is_extensible (ts->u.derived)) + return; - sprintf (name, "__tmp_class_%s", ts->u.derived->name); + if (ts->type == BT_CLASS) + sprintf (name, "__tmp_class_%s", ts->u.derived->name); + else + sprintf (name, "__tmp_type_%s", ts->u.derived->name); gfc_get_sym_tree (name, gfc_current_ns, &tmp, false); gfc_add_type (tmp->n.sym, ts, NULL); -/* Copy across the array spec to the selector. */ if (select_type_stack->selector->ts.type == BT_CLASS - && (CLASS_DATA (select_type_stack->selector)->attr.dimension - || CLASS_DATA (select_type_stack->selector)->attr.codimension)) + && select_type_stack->selector->attr.class_ok) { - tmp->n.sym->attr.pointer = 1; - tmp->n.sym->attr.dimension - = CLASS_DATA (select_type_stack->selector)->attr.dimension; - tmp->n.sym->attr.codimension - = CLASS_DATA (select_type_stack->selector)->attr.codimension; - tmp->n.sym->as - = gfc_copy_array_spec (CLASS_DATA (select_type_stack->selector)->as); + tmp->n.sym->attr.pointer + = CLASS_DATA (select_type_stack->selector)->attr.class_pointer; + + /* Copy across the array spec to the selector. */ + if ((CLASS_DATA (select_type_stack->selector)->attr.dimension + || CLASS_DATA (select_type_stack->selector)->attr.codimension)) + { + tmp->n.sym->attr.dimension + = CLASS_DATA (select_type_stack->selector)->attr.dimension; + tmp->n.sym->attr.codimension + = CLASS_DATA (select_type_stack->selector)->attr.codimension; + tmp->n.sym->as + = gfc_copy_array_spec (CLASS_DATA (select_type_stack->selector)->as); + } } gfc_set_sym_referenced (tmp->n.sym); gfc_add_flavor (&tmp->n.sym->attr, FL_VARIABLE, name, NULL); tmp->n.sym->attr.select_type_temporary = 1; - gfc_build_class_symbol (&tmp->n.sym->ts, &tmp->n.sym->attr, - &tmp->n.sym->as, false); - - return tmp; -} - - -static void -select_type_set_tmp (gfc_typespec *ts) -{ - gfc_symtree *tmp; - if (!ts) - { - select_type_stack->tmp = NULL; - return; - } - - if (!gfc_type_is_extensible (ts->u.derived)) - return; - - /* Logic is a LOT clearer with separate functions for class and derived - type temporaries! There are not many more lines of code either. */ if (ts->type == BT_CLASS) - tmp = select_class_set_tmp (ts); - else - tmp = select_derived_set_tmp (ts); - - if (tmp == NULL) - return; + gfc_build_class_symbol (&tmp->n.sym->ts, &tmp->n.sym->attr, + &tmp->n.sym->as, false); /* Add an association for it, so the rest of the parser knows it is an associate-name. The target will be set during resolution. */ |