https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126116
Bug ID: 126116
Summary: Internal file I/O corrupts NEWUNIT state, causing
subsequent CLOSE/INQUIRE to segfault
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libfortran
Assignee: unassigned at gcc dot gnu.org
Reporter: ryu.ichikawa323 at gmail dot com
Target Milestone: ---
[Description]
Performing an internal file I/O (such as WRITE to a character variable)
incorrectly corrupts the internal unit management table in libgfortran.
Specifically, the internal file I/O implicitly marks the next candidate
negative unit number to be allocated by NEWUNIT (which is -10 in a clean
environment) as `opened=.true.`.
Consequently, a subsequent CLOSE or INQUIRE(name=...) on this corrupted unit
number causes a segmentation fault because the internal file structure pointers
are uninitialized or null.
Furthermore, there is a severe inconsistency: even though unit -10 is wrongly
marked as `opened=.true.` after the internal file I/O, a subsequent OPEN
statement with `NEWUNIT` will still mistakenly allocate this exact unit -10,
compounding the state corruption.
This issue reproduces on the latest trunk (17.0.0) via Compiler Explorer.
[Steps to Reproduce]
Run the following minimal reproducible example:
program check
implicit none
character(50) :: chr
integer :: target_unit
target_unit = -10
! 1. Perform an internal file I/O
write(chr, *) "testline"
! 2. CLOSE on unit -10, which was never opened by the user.
! This causes a segmentation fault.
close(target_unit)
end program
[Actual Results]
The program terminates with the following Fortran runtime error during CLOSE on
unit -10:
"Fortran runtime error: Unit number is negative with no associated file"
(Note: In older versions like 14.2.0, this causes a Segmentation Fault. In the
latest trunk, it is caught by runtime checks, but the underlying state
corruption remains exactly the same.)
[Expected Results]
Internal file I/O should be completely isolated from external unit numbers. It
should never affect the state of any negative unit numbers. CLOSE on an
unopened unit should be a safe no-op instead of causing a runtime error.