The fix for > PR fortran/95104 - Segfault on a legal WAIT statement > > Referencing a unit in a WAIT statement that has not been opened before > resulted in a NULL pointer dereference. Check for this condition. > > 2020-05-26 Harald Anlauf <anl...@gmx.de> > > libgfortran/ > PR libfortran/95104 > * io/transfer.c (st_wait_async): Do not dereference NULL pointer. > > gcc/testsuite/ > PR libfortran/95104 > * gfortran.dg/pr95104.f90: New test. > > Co-Authored-By: Steven G. Kargl <ka...@gcc.gnu.org>
did uncover a latent issue with regard to unit locking that was introduced in the context of asynchronous I/O in libgfortran. This was reported by Rainer Orth, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95104#c13 I can reproduce this when compiling/linking with -fopenmp. There are two possible fixes for this: (1) guard the call to unlock_unit by: diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index cd51679ff46..296be0711a2 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -4508,7 +4508,8 @@ st_wait_async (st_parameter_wait *wtp) async_wait (&(wtp->common), u->au); } - unlock_unit (u); + if (u) + unlock_unit (u); } (2) in unlock_unit(): diff --git a/libgfortran/io/unit.c b/libgfortran/io/unit.c index 0030d7e8701..a3b0656cb90 100644 --- a/libgfortran/io/unit.c +++ b/libgfortran/io/unit.c @@ -767,9 +767,12 @@ close_unit_1 (gfc_unit *u, int locked) void unlock_unit (gfc_unit *u) { - NOTE ("unlock_unit = %d", u->unit_number); - UNLOCK (&u->lock); - NOTE ("unlock_unit done"); + if (u) + { + NOTE ("unlock_unit = %d", u->unit_number); + UNLOCK (&u->lock); + NOTE ("unlock_unit done"); + } } /* close_unit()-- Close a unit. The stream is closed, and any memory Does anybody prefer one over the other, or just commit both (which might be preferable to catch other unguarded cases)? Thanks, Harald