This change adds runtime routines and tests for LBOUND when passed a DIM argument, SIZE, and UBOUND when not passed a DIM argument.
Associated changes for lowering have already been merged into fir-dev.
Differential Revision: https://reviews.llvm.org/D119360
Corrects the runtime implementation of I/O on files with
the access mode ACCESS='STREAM'. This is a collection
of edge-case tweaks to ensure that the distinctions between
stream and direct/sequential files, unformatted or formatted,
are respected where appropriate.
Moves NextInField() from io-stmt.h to io-stmt.cpp --
it was getting too big to keep in a header.
This patch exposed a problem with the I/O runtime
on Windows and it was reverted. This version also
fixes that problem; files are now opened on Windows
in binary mode to prevent inadvertent insertions of
carriage returns before line feeds, and those line
endings (CR+LF) are now explicitly generated.
Differential Revision: https://reviews.llvm.org/D119015
When a mode flag is modified (e.g., BLANK='ZERO') in an I/O data transfer
statement, ensure that the right set of mode flags is modified.
There's one set of mode flags that are captured by an OPEN
statement and maintained in the connection, and another that
is maintained in an I/O statement state record for local mutability.
Some I/O API routines were unconditionally modifying the persistent
set of flags.
Differential Revision: https://reviews.llvm.org/D118835
Corrects the runtime implementation of I/O on files with
the access mode ACCESS='STREAM'. This is a collection
of edge-case tweaks to ensure that the distinctions between
stream and direct/sequential files, unformatted or formatted,
are respected where appropriate.
Moves NextInField() from io-stmt.h to io-stmt.cpp --
it was getting too big to keep in a header.
Differential Revision: https://reviews.llvm.org/D118834
NAMELIST I/O was inconsistent in its choice of which set of I/O modes
to set the "inNamelist" flag. The wrong choice was in the set of modes
that are part of the persistent state of an I/O connection; the right
place is the set of modes that are reinitialized at the beginning of
each I/O statement so that they can be modified by READ/WRITE control
list specifiers and FORMAT control edit descriptors. Fix.
Differential Revision: https://reviews.llvm.org/D118745
A blank field in an input record that exists must be interpreted
as a zero value for numeric input editing, but advancing to a
next record that doesn't exist should leave an input variable
unmodified (and signal END=). On internal output, blank fill
the "current record" array element even if nothing has been
written to it if it is the only record.
Differential Revision: https://reviews.llvm.org/D118720
As per Steve Scalpone's suggestion, I've renamed the runtime routine to
better evoke its purpose.
I implemented a routine called "Crash" and added a test.
Differential Revision: https://reviews.llvm.org/D118703
Use a bit-set to manage runtime-generated I/O unit numbers, recycle
them after they're closed, and use a range of values that fits in
a minimal-sized integer.
Differential Revision: https://reviews.llvm.org/D118651
When reallocating an I/O buffer to accommodate a large record,
ensure that the amount of growth is at least as large as the
minimum initial record size (64KiB). The previous policy was
causing input buffer reallocation for each byte after the minimum
buffer size when scanning input data for record termination
newlines.
Differential Revision: https://reviews.llvm.org/D118649
When RECL= is set on OPEN(), ensure that it:
1) enforces a max output record payload size
(not including header+footer or newline), and
2) causes padding of short output records only
for ACCESS='DIRECT'
The previous code was causing some false overrun errors
and applying padding to sequential/stream output files.
Differential Revision: https://reviews.llvm.org/D118630
In user-defined derived type I/O to an external unit, don't
omit the format string from the constructor of ChildFormattedIoStatement.
And include any user IOMSG text in the crash message of the
parent, if it doesn't catch errors.
Differential Revision: https://reviews.llvm.org/D117903
User-defined derived type editing in formatted I/O wasn't
working with repeat counts; e.g., "2DT(10)". The solution required
some code to be moved from GetNextDataEdit() to CueUpNextDataEdit() so
that a stack entry for a nonparenthesized repeated data edit
descriptor would work correctly -- all other data edit descriptors
are capable of dealing with repetition in their callees, so the bug
hadn't been exposed before.
Debugging this problem led to some improvements in error messages
for bad format strings, and those changes have been retained; also,
a dead member function was discovered and expunged.
Differential Revision: https://reviews.llvm.org/D117904
Implements a near-universal extension in which NAMELIST
input will skip over unrelated namelist groups in the
input stream until the group with the requested name appears.
Differential Revision: https://reviews.llvm.org/D117843
Array subscripts and substring limits in NAMELIST input are
allowed to bear an explicit plus sign.
Differential Revision: https://reviews.llvm.org/D117818
The unit number passed to a FLUSH statement is not required to
be a valid open unit; nothing happens (esp. not the creation of
an empty fort.n file) in this case.
Differential Revision: https://reviews.llvm.org/D117819
Don't let a program set a fixed RECL= on a connected unit unless
it already had one with the same value.
Differential Revision: https://reviews.llvm.org/D117595
Implements substring references into potentially partial CHARACTER
scalars and array elements in NAMELIST input.
Differential Revision: https://reviews.llvm.org/D117576
Internal writes to character arrays should not blank-fill
records (elements) past the last one that was written to.
Differential Revision: https://reviews.llvm.org/D117342
After an ENDFILE statement, a WRITE is an error without
a prior BACKSPACE. Also fix the return value for the case
of formatted integer input with no input digits to be false
(exposed by new test).
Differential Revision: https://reviews.llvm.org/D117346
- Join indirection and rank into a single value `flags`
- Make the struct a plain C struct.
Reviewed By: schweitz
Differential Revision: https://reviews.llvm.org/D115464
Prior to the introduction of the FLUSH statement in Fortran 2003,
implementations provided a FLUSH subroutine.
We can't yet put Fortran code into the runtime, so this subroutine
is in C++ with a Fortran-mangled entry point name.
Differential Revision: https://reviews.llvm.org/D115289
This patch adds the runtime function to allocate and
deallocate ragged arrays.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D114534
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
In error cases it is possible to CLOSE a unit that has not
been successfully connected, so don't crash when the file descriptor
is negative.
Differential Revision: https://reviews.llvm.org/D115165
When closing all open units, don't hold the unit map lock
over the actual close operations; if one of those aborts,
CloseAll() may be called and then deadlock.
Differential Review: https://reviews.llvm.org/D115184
RECL= is required for direct access I/O, but is permitted
as well for sequential I/O, where it is defined by the
standard to specify a maximum record (line) length.
The standard does not say what should happen when an
sequential formatted input record appears whose length is
unequal to RECL= when it is specified.
Precedents from other compilers are unclear: one raises an error,
some honor RECL= as an effective truncation, and a few ignore the
situation. On output, all other compilers tested raised an
error when an attempt is made to emit a record longer than RECL=.
This patch treats RECL= as effective truncation on input and
as a hard limit with error on output, and also ensures that
RECL= can be set *longer* than the actual input record lengths.
Differential Revision: https://reviews.llvm.org/D115102
In TRANSFER runtime the result was an array only if the MOLD was an array.
This is not in line with TRANSFER definition in 16.9.193 that rules that it
must also be an array if MOLD is scalar and SIZE if provided.
Differential Revision: https://reviews.llvm.org/D114943
STOP statement output was sometimes failing to appear because
the runtime flushes and shuts down open Fortran units beforehand.
But when file descriptor 2 was closed, the STOP statement output
was suppressed. The fix is to not actually close file descriptors
0-2 if they are connected to Fortran units being closed. This was
already the policy when an OPEN statement was (re-)opening such a
unit, so that logic has been pulled out into a member function and
shared with CLOSE processing.
Differential Revision: https://reviews.llvm.org/D114897
Create a new flang/runtime/support.cpp module to hold miscellaneous
runtime APIs to support lowering, and define an API IsContiguous() to
wrap the member function predicate Descriptor::IsContiguous().
And do a little clean-up of other API headers that don't need to expose
Runtime/descriptor.h.
Differential Revision: https://reviews.llvm.org/D114752
INQUIRE(POSITION=)'s results need to reflect the POSITION=
specifier used for the OPEN statement until the unit has been
repositioned. Preserve the POSITION= from OPEN and used it
for INQUIRE(POSITION=) until is becomes obsolete.
INQUIRE(PAD=) is implemented here in the case of an unconnected unit
with Fortran 2018 semantics; i.e., "UNDEFINED", rather than Fortran 90's
"YES"/"NO" (see 4.3.6 para 2). Apparent failures with F'90-only tests
will persist with INQUIRE(PAD=); these discrepancies don't seem to warrant
an option or environment variable.
To make the implementation of INQUIRE more closely match the language
in the standard, rename IsOpen() to IsConnected(), and use it explicitly
for the various INQUIRE specifiers.
Differential Revision: https://reviews.llvm.org/D114755
RESHAPE() fails inappropriately at runtime if the source array
is larger than the result -- which is perfectly valid -- because
of an obviously reversed comparison of their numbers of elements
is activating the runtime asserts meant for the opposite case
(source smaller than result).
Differential Revision: https://reviews.llvm.org/D114474
A recent patch to real/complex formatted input included what must
have been an editing hiccup: "++ ++p" instead of "++p". This
compiles, and it broke the consumption of the trailing ')' of a
complex value in namelist input by skipping over the character.
Extend existing test to cover this case.
Differential Revision: https://reviews.llvm.org/D114297
This is a near-universal language extension; external unit 0
is preconnected to the standard error output.
Differential Revision: https://reviews.llvm.org/D114298
In 'STOP bye bye', do not print 'Fortran STOP:` before 'bye bye' when
NO_STOP_MESSAGE environment variable is set at runtime.
Also only exit with code 1 in StopStatementText if this is an ERROR STOP.
This matches other compiler behaviors.
Move STOP related unit tests in their own test file and add new tests to
cover this change.
Differential Revision: https://reviews.llvm.org/D114152
The predefined units were not being initialized with FORM='FORMATTED',
so INQUIRE(PAD=) was failing if no I/O had already been done.
INQUIRE(POSITION=) was returning 'REWIND' on stdin/stdout (which
is somewhat defensible from the definition, and is what Intel Fortran
does), but most implementations return 'ASIS'. Change the runtime
to return 'REWIND' only for positionable external files, but 'ASIS'
for terminals, sockets, &c.
Differential Revision: https://reviews.llvm.org/D114028
The inquire by output list form of the INQUIRE statement calculates the
number of file storage units that would be required to store the data
of an output list in an unformatted file. Currently, the result is
incorrectly multiplied by the number of bytes for a data type. A query
for "INTEGER(KIND=4) A(10)" should be 40, not 160.
Update formatting.
1. To avoid overwriting the part of the record read in the non advancing read,
the furtherPositionInRecord field must be set to the max of the
furtherPositionInRecord and the positionInRecord at the beginning of the
IO write.
2. To allow any further read to succeed after the write, the unit
beganReadingRecord_ must be set to false when resetting the recordLength
during the write, otherwise, recordLength will not be computed in further
read and an assert is hit (at unit.cpp(398)).
The added unit test exercises both of these scenarios.
Differential Revision: https://reviews.llvm.org/D113740
Profiling a basic internal real input read benchmark shows some
hot spots in the code used to prepare input for decimal-to-binary
conversion, which is of course where the time should be spent.
The library that implements decimal to/from binary conversions has
been optimized, but not the code in the Fortran runtime that calls it,
and there are some obvious light changes worth making here.
Move some member functions from *.cpp files into the class definitions
of Descriptor and IoStatementState to enable inlining and specialization.
Make GetNextInputBytes() the new basic input API within the
runtime, replacing GetCurrentChar() -- which is rewritten in terms of
GetNextInputBytes -- so that input routines can have the
ability to acquire more than one input character at a time
and amortize overhead.
These changes speed up the time to read 1M random reals
using internal I/O from a character array from 1.29s to 0.54s
on my machine, which on par with Intel Fortran and much faster than
GNU Fortran.
Differential Revision: https://reviews.llvm.org/D113697
When an Fw.d output edit descriptor has a "d" value exactly
equal to the number of zeroes after the decimal point for a value
(e.g., 0.07 with F5.1), the Fw.d output editing code needs to
do the rounding itself to either 0.0 or 0.1 after performing
a conversion without rounding (to avoid 0.04999 rounding up twice).
Differential Revision: https://reviews.llvm.org/D113698
When an environment variable NO_STOP_MESSAGE=1 is set,
assume that STOP statements with a successful code
have QUIET=.TRUE.
Differential Revision: https://reviews.llvm.org/D113701
The ORDER= argument to the transformational intrinsic function RESHAPE
was being misinterpreted in an inverted way that could be detected only
with 3-d or higher rank array. Fix in both folding and the runtime, and
extend tests.
Differential Revision: https://reviews.llvm.org/D113699
The source index should not be compared to zero after applying the
shift with the modulo, it must be compared to the lower bound.
Otherwise, the extent is not added in case it should and the computed
source index may be less than the lower bound, causing invalid results.
Differential Revision: https://reviews.llvm.org/D113659
Component::CreatePointerDescriptor unconditionally expects a
vector of subscripts to be passed as an argument, but is called
from NAMELIST input with a null pointer. Make that argument
a nullable pointer, move it to the end of the argument list,
and give it a default value of nullptr.
Differential Revision: https://reviews.llvm.org/D113312