{
if (context)
{
- if (assoc->target->expr_type == EXPR_VARIABLE)
+ if (assoc->target->expr_type == EXPR_VARIABLE
+ && gfc_has_vector_index (assoc->target))
gfc_error ("%qs at %L associated to vector-indexed target"
" cannot be used in a variable definition"
" context (%s)",
else if (selector->ts.type == BT_CLASS
&& CLASS_DATA (selector)
&& CLASS_DATA (selector)->as
- && ref && ref->type == REF_ARRAY)
+ && ((ref && ref->type == REF_ARRAY)
+ || selector->expr_type == EXPR_OP))
{
/* Ensure that the array reference type is set. We cannot use
gfc_resolve_expr at this point, so the usable parts of
resolve.cc(resolve_array_ref) are employed to do it. */
- if (ref->u.ar.type == AR_UNKNOWN)
+ if (ref && ref->u.ar.type == AR_UNKNOWN)
{
ref->u.ar.type = AR_ELEMENT;
for (int i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
}
}
- if (ref->u.ar.type == AR_FULL)
+ if (!ref || ref->u.ar.type == AR_FULL)
selector->rank = CLASS_DATA (selector)->as->rank;
else if (ref->u.ar.type == AR_SECTION)
selector->rank = ref->u.ar.dimen;
if (rank)
{
- for (int i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
- if (ref->u.ar.dimen_type[i] == DIMEN_ELEMENT
- || (ref->u.ar.dimen_type[i] == DIMEN_UNKNOWN
- && ref->u.ar.end[i] == NULL
- && ref->u.ar.stride[i] == NULL))
- rank--;
+ if (ref)
+ {
+ for (int i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
+ if (ref->u.ar.dimen_type[i] == DIMEN_ELEMENT
+ || (ref->u.ar.dimen_type[i] == DIMEN_UNKNOWN
+ && ref->u.ar.end[i] == NULL
+ && ref->u.ar.stride[i] == NULL))
+ rank--;
+ }
if (rank)
{
bool dual_locus_error;
bool t = true;
+ /* Reduce stacked parentheses to single pair */
+ while (e->expr_type == EXPR_OP
+ && e->value.op.op == INTRINSIC_PARENTHESES
+ && e->value.op.op1->expr_type == EXPR_OP
+ && e->value.op.op1->value.op.op == INTRINSIC_PARENTHESES)
+ {
+ gfc_expr *tmp = gfc_copy_expr (e->value.op.op1);
+ gfc_replace_expr (e, tmp);
+ }
+
/* Resolve all subnodes-- give them types. */
switch (e->value.op.op)
{
gfc_ref *nref = (*expr1)->ref;
gfc_symbol *sym1 = (*expr1)->symtree->n.sym;
- gfc_symbol *sym2 = expr2 ? expr2->symtree->n.sym : NULL;
+ gfc_symbol *sym2;
+ gfc_expr *selector = gfc_copy_expr (expr2);
+
(*expr1)->rank = rank;
+ if (selector)
+ {
+ gfc_resolve_expr (selector);
+ if (selector->expr_type == EXPR_OP
+ && selector->value.op.op == INTRINSIC_PARENTHESES)
+ sym2 = selector->value.op.op1->symtree->n.sym;
+ else if (selector->expr_type == EXPR_VARIABLE
+ || selector->expr_type == EXPR_FUNCTION)
+ sym2 = selector->symtree->n.sym;
+ else
+ gcc_unreachable ();
+ }
+ else
+ sym2 = NULL;
+
if (sym1->ts.type == BT_CLASS)
{
if ((*expr1)->ts.type != BT_CLASS)
class(test_t), intent(inout) :: obj
integer, intent(in) :: a
associate (state => obj%state(TEST_STATES)) ! { dg-error "no IMPLICIT type" }
- state = a ! { dg-error "vector-indexed target" }
+ state = a ! { dg-error "cannot be used in a variable definition context" }
! state(TEST_STATE) = a
end associate
end subroutine test_alter_state2
--- /dev/null
+! { dg-do compile }
+!
+! Check the fix for PR104625 in which the selectors in parentheses used
+! to cause ICEs. The "Unclassifiable statement" errors were uncovered once
+! the ICEs were fixed.
+!
+! Contributed by Gerhard Steinmetz <gscfq@t-online.de>
+!
+program p
+ implicit none
+ type t
+ integer :: a
+ end type
+contains
+ subroutine s(x)
+! class(t) :: x ! Was OK
+ class(t) :: x(:) ! Used to ICE in combination with below
+ class(t), allocatable :: r(:)
+
+ select type (y => x) ! OK
+ type is (t)
+ y%a = 99
+ end select
+ select type (z => (x)) ! Used to ICE
+ type is (t)
+ r = z(1) ! Used to give "Unclassifiable statement" error
+ z%a = 99 ! { dg-error "cannot be used in a variable definition" }
+ end select
+ select type (u => ((x))) ! Used to ICE
+ type is (t)
+ r = u(1) ! Used to give "Unclassifiable statement" error
+ u%a = 99 ! { dg-error "cannot be used in a variable definition" }
+ end select
+ end
+end