https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103695
--- Comment #3 from sandra at gcc dot gnu.org --- It appears that the wrong-scope problem is introduced in gfc_finish_var_decl, in this block of code: /* Chain this decl to the pending declarations. Don't do pushdecl() because this would add them to the current scope rather than the function scope. */ if (current_function_decl != NULL_TREE) { if (sym->ns->proc_name && (sym->ns->proc_name->backend_decl == current_function_decl || sym->result == sym)) gfc_add_decl_to_function (decl); else if (sym->ns->proc_name && sym->ns->proc_name->attr.flavor == FL_LABEL) /* This is a BLOCK construct. */ add_decl_as_local (decl); else gfc_add_decl_to_parent_function (decl); } ns->proc_name contains something completely unexpected here so it's falling through to gfc_add_decl_to_parent_function. I think it's an accident that it works at all when it's not inside a nested function. Do we really want these iterator variables to have local scope instead? gfortran.h documents the proc_name field as /* If this is a namespace of a procedure, this points to the procedure. */ struct gfc_symbol *proc_name; but the ASSOCIATED clause seems to be using it for an entirely different purpose, to chain the list of iterator variables (see handle_iterator in trans-openmp.c). I think that's the real bug, rather than the code snippet quoted above. It ought to be adding a new field to struct gfc_namespace if there isn't a better place to store this information, instead of overloading one that means something else. I'm still trying to find my way around the code that manipulates these namespaces and iterator variables. There's an annoying lack of comments here to explain the data structures it is using or what parts are handled during gimplification. :-(