/* For variable targets, we get some attributes from the target. */
if (target->expr_type == EXPR_VARIABLE)
{
- gfc_symbol* tsym;
+ gfc_symbol *tsym, *dsym;
gcc_assert (target->symtree);
tsym = target->symtree->n.sym;
- if (tsym->attr.subroutine
- || tsym->attr.external
- || (tsym->attr.function && tsym->result != tsym))
+ if (gfc_expr_attr (target).proc_pointer)
{
- gfc_error ("Associating entity %qs at %L is a procedure name",
+ gfc_error ("Associating entity %qs at %L is a procedure pointer",
tsym->name, &target->where);
return;
}
- if (gfc_expr_attr (target).proc_pointer)
+ if (tsym->attr.flavor == FL_PROCEDURE && tsym->generic
+ && (dsym = gfc_find_dt_in_generic (tsym)) != NULL
+ && dsym->attr.flavor == FL_DERIVED)
{
- gfc_error ("Associating entity %qs at %L is a procedure pointer",
+ gfc_error ("Derived type %qs cannot be used as a variable at %L",
tsym->name, &target->where);
return;
}
+ if (tsym->attr.flavor == FL_PROCEDURE)
+ {
+ bool is_error = true;
+ if (tsym->attr.function && tsym->result == tsym)
+ for (gfc_namespace *ns = sym->ns; ns; ns = ns->parent)
+ if (tsym == ns->proc_name)
+ {
+ is_error = false;
+ break;
+ }
+ if (is_error)
+ {
+ gfc_error ("Associating entity %qs at %L is a procedure name",
+ tsym->name, &target->where);
+ return;
+ }
+ }
+
sym->attr.asynchronous = tsym->attr.asynchronous;
sym->attr.volatile_ = tsym->attr.volatile_;
--- /dev/null
+! { dg-do compile }
+!
+! PR fortran/93363
+!
+! Contributed by G. Steinmetz
+
+program p
+ type t
+ integer :: a
+ end type
+ type(t) :: z
+ z = t(1)
+ associate (var1 => t) ! { dg-error "Derived type 't' cannot be used as a variable" }
+ end associate
+end
+
+subroutine sub
+ if (f() /= 1) stop
+ associate (var2 => f) ! { dg-error "Associating entity 'f' at .1. is a procedure name" }
+ end associate
+ block
+ block
+ associate (var2a => f) ! { dg-error "Associating entity 'f' at .1. is a procedure name" }
+ end associate
+ end block
+ end block
+contains
+ integer function f()
+ f = 1
+ associate (var3 => f)
+ end associate
+ block
+ block
+ associate (var4 => f)
+ end associate
+ end block
+ end block
+ end
+ integer recursive function f2() result(res)
+ res = 1
+ associate (var5 => f2) ! { dg-error "Associating entity 'f2' at .1. is a procedure name" }
+ end associate
+ block
+ block
+ associate (var6 => f2) ! { dg-error "Associating entity 'f2' at .1. is a procedure name" }
+ end associate
+ end block
+ end block
+ end
+ subroutine subsub
+ associate (var7 => f) ! { dg-error "Associating entity 'f' at .1. is a procedure name" }
+ end associate
+ block
+ block
+ associate (var8 => f) ! { dg-error "Associating entity 'f' at .1. is a procedure name" }
+ end associate
+ end block
+ end block
+ end
+end
+
+subroutine sub2
+ interface g
+ procedure s
+ end interface
+ associate (var9 => g) ! { dg-error "Associating entity 'g' at .1. is a procedure name" }
+ end associate
+contains
+ subroutine s
+ end
+end