PR fortran/51970
PR fortran/51977
* primary.c (gfc_match_varspec. gfc_match_rvalue): Set
handle array spec for BT_CLASS.
* expr.c (gfc_get_variable_expr, gfc_lval_expr_from_sym)
* frontend-passes.c (create_var): Ditto.
* resolve.c (resolve_actual_arglist, resolve_assoc_var): Ditto.
* trans-decl.c (gfc_trans_deferred_vars): Use class_pointer
instead of attr.pointer.
(gfc_generate_function_code): Use CLASS_DATA (sym) for BT_CLASS.
* trans-intrinsic.c (conv_intrinsic_move_alloc): Move assert.
* trans-stmt.c (trans_associate_var): Ask for the descriptor.
2012-01-27 Tobias Burnus <burnus@net-b.de>
PR fortran/51970
PR fortran/51977
* gfortran.dg/move_alloc_13.f90: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183622
138bc75d-0d04-0410-961f-
82ee72b054a4
2012-01-27 Tobias Burnus <burnus@net-b.de>
+ PR fortran/51970
+ PR fortran/51977
+ * primary.c (gfc_match_varspec. gfc_match_rvalue): Set
+ handle array spec for BT_CLASS.
+ * expr.c (gfc_get_variable_expr, gfc_lval_expr_from_sym)
+ * frontend-passes.c (create_var): Ditto.
+ * resolve.c (resolve_actual_arglist, resolve_assoc_var): Ditto.
+ * trans-decl.c (gfc_trans_deferred_vars): Use class_pointer
+ instead of attr.pointer.
+ (gfc_generate_function_code): Use CLASS_DATA (sym) for BT_CLASS.
+ * trans-intrinsic.c (conv_intrinsic_move_alloc): Move assert.
+ * trans-stmt.c (trans_associate_var): Ask for the descriptor.
+
+2012-01-27 Tobias Burnus <burnus@net-b.de>
+
PR fortran/51953
* match.c (gfc_match_allocate): Allow more than allocate
object with SOURCE=.
e->symtree = var;
e->ts = var->n.sym->ts;
- if (var->n.sym->as != NULL)
+ if ((var->n.sym->as != NULL && var->n.sym->ts.type != BT_CLASS)
+ || (var->n.sym->ts.type == BT_CLASS && CLASS_DATA (var->n.sym)
+ && CLASS_DATA (var->n.sym)->as))
{
- e->rank = var->n.sym->as->rank;
+ e->rank = var->n.sym->ts.type == BT_CLASS
+ ? CLASS_DATA (var->n.sym)->as->rank : var->n.sym->as->rank;
e->ref = gfc_get_ref ();
e->ref->type = REF_ARRAY;
e->ref->u.ar.type = AR_FULL;
lval->ref->u.ar.type = AR_FULL;
lval->ref->u.ar.dimen = lval->rank;
lval->ref->u.ar.where = sym->declared_at;
- lval->ref->u.ar.as = sym->as;
+ lval->ref->u.ar.as = sym->ts.type == BT_CLASS
+ ? CLASS_DATA (sym)->as : sym->as;
}
return lval;
result->ref->type = REF_ARRAY;
result->ref->u.ar.type = AR_FULL;
result->ref->u.ar.where = e->where;
- result->ref->u.ar.as = symbol->as;
+ result->ref->u.ar.as = symbol->ts.type == BT_CLASS
+ ? CLASS_DATA (symbol)->as : symbol->as;
if (gfc_option.warn_array_temp)
gfc_warning ("Creating array temporary at %L", &(e->where));
}
&& (CLASS_DATA (sym)->attr.dimension
|| CLASS_DATA (sym)->attr.codimension)))
{
+ gfc_array_spec *as;
+
+ tail = extend_ref (primary, tail);
+ tail->type = REF_ARRAY;
+
/* In EQUIVALENCE, we don't know yet whether we are seeing
an array, character variable or array of character
variables. We'll leave the decision till resolve time. */
- tail = extend_ref (primary, tail);
- tail->type = REF_ARRAY;
- m = gfc_match_array_ref (&tail->u.ar, equiv_flag ? NULL : sym->as,
- equiv_flag,
- sym->ts.type == BT_CLASS && CLASS_DATA (sym)
- ? (CLASS_DATA (sym)->as
- ? CLASS_DATA (sym)->as->corank : 0)
- : (sym->as ? sym->as->corank : 0));
+ if (equiv_flag)
+ as = NULL;
+ else if (sym->ts.type == BT_CLASS && CLASS_DATA (sym))
+ as = CLASS_DATA (sym)->as;
+ else
+ as = sym->as;
+
+ m = gfc_match_array_ref (&tail->u.ar, as, equiv_flag,
+ as ? as->corank : 0);
if (m != MATCH_YES)
return m;
e->value.function.actual = actual_arglist;
e->where = gfc_current_locus;
- if (sym->as != NULL)
+ if (sym->ts.type == BT_CLASS && sym->attr.class_ok
+ && CLASS_DATA (sym)->as)
+ e->rank = CLASS_DATA (sym)->as->rank;
+ else if (sym->as != NULL)
e->rank = sym->as->rank;
if (!sym->attr.function
got_variable:
e->expr_type = EXPR_VARIABLE;
e->ts = sym->ts;
- if (sym->as != NULL)
+ if ((sym->as != NULL && sym->ts.type != BT_CLASS)
+ || (sym->ts.type == BT_CLASS && sym->attr.class_ok
+ && CLASS_DATA (sym)->as))
{
- e->rank = sym->as->rank;
+ e->rank = sym->ts.type == BT_CLASS
+ ? CLASS_DATA (sym)->as->rank : sym->as->rank;
e->ref = gfc_get_ref ();
e->ref->type = REF_ARRAY;
e->ref->u.ar.type = AR_FULL;
- e->ref->u.ar.as = sym->as;
+ e->ref->u.ar.as = sym->ts.type == BT_CLASS
+ ? CLASS_DATA (sym)->as : sym->as;
}
/* Expressions are assigned a default ts.type of BT_PROCEDURE in
sym->attr.asynchronous = tsym->attr.asynchronous;
sym->attr.volatile_ = tsym->attr.volatile_;
- if (tsym->ts.type == BT_CLASS)
- sym->attr.target = tsym->attr.target || CLASS_DATA (tsym)->attr.pointer;
- else
- sym->attr.target = tsym->attr.target || tsym->attr.pointer;
-
- if (sym->ts.type == BT_DERIVED && tsym->ts.type == BT_CLASS)
- target->rank = sym->as ? sym->as->rank : 0;
+ sym->attr.target = tsym->attr.target
+ || gfc_expr_attr (target).pointer;
}
/* Get type if this was not already set. Note that it can be
&& !gfc_has_vector_subscript (target));
/* Finally resolve if this is an array or not. */
- if (sym->attr.dimension
- && (target->ts.type == BT_CLASS
- ? !CLASS_DATA (target)->attr.dimension
- : target->rank == 0))
+ if (sym->attr.dimension && target->rank == 0)
{
gfc_error ("Associate-name '%s' at %L is used as array",
sym->name, &sym->declared_at);
}
else if ((!sym->attr.dummy || sym->ts.deferred)
&& (sym->ts.type == BT_CLASS
- && CLASS_DATA (sym)->attr.pointer))
+ && CLASS_DATA (sym)->attr.class_pointer))
continue;
else if ((!sym->attr.dummy || sym->ts.deferred)
&& (sym->attr.allocatable
null_pointer_node));
else if (sym->ts.type == BT_CLASS
&& CLASS_DATA (sym)->attr.allocatable
- && sym->attr.dimension == 0 && sym->result == sym)
+ && CLASS_DATA (sym)->attr.dimension == 0
+ && sym->result == sym)
{
tmp = CLASS_DATA (sym)->backend_decl;
tmp = fold_build3_loc (input_location, COMPONENT_REF,
gfc_init_se (&from_se, NULL);
gfc_init_se (&to_se, NULL);
+ gcc_assert (from_expr->ts.type != BT_CLASS
+ || to_expr->ts.type == BT_CLASS);
+
if (from_expr->rank == 0)
{
- gcc_assert (from_expr->ts.type != BT_CLASS
- || to_expr->ts.type == BT_CLASS);
if (from_expr->ts.type != BT_CLASS)
from_expr2 = from_expr;
else
gfc_se se;
gfc_init_se (&se, NULL);
+ se.descriptor_only = 1;
gfc_conv_expr (&se, e);
gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)));
2012-01-27 Tobias Burnus <burnus@net-b.de>
+ PR fortran/51970
+ PR fortran/51977
+ * gfortran.dg/move_alloc_13.f90: New.
+
+2012-01-27 Tobias Burnus <burnus@net-b.de>
+
PR fortran/51953
* gfortran.dg/allocate_alloc_opt_13.f90: New.
* gfortran.dg/allocate_alloc_opt_4.f90: Add -std=f2003
--- /dev/null
+! { dg-do run}
+!
+! PR fortran/51970
+! PR fortran/51977
+!
+type t
+end type t
+type, extends(t) :: t2
+ integer :: a
+end type t2
+
+class(t), allocatable :: y(:), z(:)
+
+allocate(y(2), source=[t2(2), t2(3)])
+call func2(y,z)
+
+select type(z)
+ type is(t2)
+ if (any (z(:)%a /= [2, 3])) call abort()
+ class default
+ call abort()
+end select
+
+contains
+ function func(x)
+ class (t), allocatable :: x(:), func(:)
+ call move_alloc (x, func)
+ end function
+
+ function func1(x)
+ class (t), allocatable :: x(:), func1(:)
+ call move_alloc (func1, x)
+ end function
+
+ subroutine func2(x, y)
+ class (t), allocatable :: x(:), y(:)
+ call move_alloc (x, y)
+ end subroutine
+end