https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119136
--- Comment #15 from Thomas Koenig <tkoenig at gcc dot gnu.org> ---
(In reply to Jerry DeLisle from comment #14)
> Created attachment 63178 [details]
> Preliminary patch that partially fixes this
>
> The attached patch detects external file recurise I/O. As noted in the
> comment, internal units needs to be handled differently. I am still sorting
> it out. As is, this regression tests OK.
A few nits/questions:
I do not think gfc_unit is externally visible, so it might make
sense to put is_active together with has_size, to save a few bytes.
The pre-existing comment for get_gfc_unit_from_unit_root is wrong: It says
/* get_gfc_unit_from_root()-- Given an integer, return a pointer
to the unit structure. Returns NULL if the unit does not exist,
otherwise returns a locked unit. */
but no locking is done. This could be adjusted in the patch.
Regarding the logic: I think we have the potential for race conditions
here. I would suggest something like (completely untested)
void
check_for_recursive (st_parameter_dt *dtp)
{
gfc_unit *p;
p = get_gfc_unit_from_unit_root(dtp->common.unit);
if (p != NULL)
{
if (!(dtp->common.flags & IOPARM_DT_HAS_INTERNAL_UNIT))
{
/* The unit is external. */
/* If the unit is locked by somebody else, something is certainly
wrong. */
if (TRYLOCK(&p->lock)) {
generate_error (&dtp->common, LIBERROR_RECURSIVE_IO, NULL);
return;
}
if (p->is_active && (p->child_dtio == 0))
generate_error (&dtp->common, LIBERROR_RECURSIVE_IO, NULL);
else
p->is_active = true;
UNLOCK(&p->lock);
}
else
{
/* Checking an internal unit will have to be different. */
}
}
}