When using `setsid()` in a child process created by `fork()`, a new
session is created, and the child becomes a session leader. If the
parent process terminates before the child, the child becomes an orphan
and is adopted by the `init` process. The `init` process will eventually
clean up the child process once it exits.
However, killing the parent does not automatically kill the child; the
child will continue running until it exits.
Proper cleanup involves waiting for the child process to exit using
`wait()` or `waitpid()` in the parent process to avoid zombie processes,
but this approach is not valid for `EXECUTE_COMMAND_LINE` with async
mode.
Fix: https://github.com/llvm/llvm-project/issues/77803
When an already-allocated allocatable array is about to fail
reallocation, don't allow its size or other characteristics to be
changed.
Fixes
llvm-test-suite/Fortran/gfortran/regression/multiple_allocation_1.f90
and .../multiple_allocation_3.f90.
The Fortran standard defines real MOD and MODULO with expressions like
MOD(a,p) = a - AINT(a/p)*p. Unfortunately, these definitions have poor
accuracy when a is much larger in magnitude than p, and every Fortran
compiler uses better algorithms instead.
Fixes llvm-test-suite/Fortran/gfortran/regression/mod_large_1.f90.
This reverts commit cab156c4129e5948a6322054480e66d3ca17b919, and adds
language to Extensions.md documenting the discrepancy with the letter of
the language standard.
Detect NaN elements in data and handle them like gfortran does (at
runtime); namely, NaN can be returned if all the data are NaNs, but any
non-NaN value is preferable. Ensure that folding returns the same
results as runtime computation.
Fixes llvm-test-suite/Fortran/gfortran/regression/maxloc_2.f90 (and
probably others).
The implementation of MAXLOC/MINLOC without DIM=1 is wrong for CHARACTER
data -- change it to use the character comparator rather than the
numeric comparator.
Fixes llvm-test-suite/Fortran/gfortran/regression/maxloc_string_1.f90.
As NAMELIST output is a variant of list-directed output, its editing
must produce leading spaces on (most) output records to effect carriage
control. These spaces are required by the language standard and
implemented by nearly all other Fortran compilers (except GNU).
Fixes https://github.com/llvm/llvm-project/issues/76798.
…field
When a comma appears in a fixed-width input field for integer editing,
many compilers accept it without error and interpret the comma as
terminating the field early.
Support \uNNNN and \uNNNNNNNN escape sequences for CHARACTER(KIND=2) and
CHARACTER(KIND=4) literal constants for better GNU Fortran
compatibility.
Fixes llvm-test-suite/Fortran/gfortran/regression/achar_6.F90 and
.../widechar_1.f90.
The FreeMemory function only accepts a void pointer, but it was being
called with a const char pointer, resulting in a type-casting issue.
To address this, the const was removed, use char * instead.
This reverts commit 4210eb1d704c3ba602328efc8924147b2e98ed18.
I didn't realise this was going to break every -Werror bot,
so I guess we'll take the test suite failure until a fix is found,
it's less disruptive.
This reverts commit 18734f606635f4f4270f911b68060890ce3dd94a.
This caused a test suite failure on our bots:
https://lab.llvm.org/buildbot/#/builders/184/builds/9407
```
$ ~/stage1.install/bin/flang-new flush_1.f90
/usr/bin/ld: /home/david.spickett/stage1.install/lib/libFortranRuntime.a(extensions.cpp.o): in function `getlog_':
extensions.cpp:(.text.getlog_+0x1c): undefined reference to `operator new(unsigned long)'
/usr/bin/ld: extensions.cpp:(.text.getlog_+0x7c): undefined reference to `operator delete(void*)'
/usr/bin/ld: extensions.cpp:(.text.getlog_+0xc4): undefined reference to `operator delete(void*)'
/usr/bin/ld: extensions.cpp:(.text.getlog_+0xe8): undefined reference to `operator delete(void*)'
flang-new: error: linker command failed with exit code 1 (use -v to see invocation)
```
Linux defines WEXITSTATUS in stdlib.h, but at least FreeBSD and NetBSD
only define it in sys/wait.h. Include this header unconditionally, since
it is required on the BSDs and should be harmless on other platforms.
Fixes FreeBSD build after #74077.
18af032c0e16252effeb6dfd02113812388f1d31 broke the Solaris build:
```
/vol/llvm/src/llvm-project/dist/flang/runtime/extensions.cpp:60:24: error: use of undeclared identifier 'LOGIN_NAME_MAX'
60 | const int nameMaxLen{LOGIN_NAME_MAX + 1};
| ^
/vol/llvm/src/llvm-project/dist/flang/runtime/extensions.cpp:61:12: warning: variable length arrays in C++ are a Clang extension [-Wvla-cxx-extension]
61 | char str[nameMaxLen];
| ^~~~~~~~~~
/vol/llvm/src/llvm-project/dist/flang/runtime/extensions.cpp:61:12: note: initializer of 'nameMaxLen' is unknown
/vol/llvm/src/llvm-project/dist/flang/runtime/extensions.cpp:60:13: note: declared here
60 | const int nameMaxLen{LOGIN_NAME_MAX + 1};
| ^
```
`flang/unittests/Runtime/CommandTest.cpp` has the same issue.
As documented in Solaris 11.4 `limits.h(3HEAD)`, `LOGIN_NAME_MAX` can be
undefined. To determine the value, `sysconf(3C)` needs to be used
instead.
Beside that portable method, Solaris also provides a non-standard
`LOGNAME_MAX` which could be used, but I've preferred the standard route
instead which would support other targets with the same issue.
Tested on `amd64-pc-solaris2.11` and `x86_64-pc-linux-gnu`.
reference to gfortran fdate
https://gcc.gnu.org/onlinedocs/gfortran/FDATE.html
usage:
```fortran
CHARACTER(32) :: time
CALL fdate(time)
WRITE(*,*) time
```
fdate is used in the ECP proxy application
https://proxyapps.exascaleproject.org/app/minismac2d/f904467142/ref/smac2d.f (L1570)
`fdate` now produce the same result on flang, compare to gfortran, where
If the length is too short to fit completely, blank return.
```fortran
character(20) :: string
call fdate(string)
write(*, *) string, "X"
```
```bash
$ ../build-release/bin/flang-new test.f90
$ ./a.out
X
```
If length if larger than it requires(24), fill the rest of buffer space.
```fortran
character(30) :: string
call fdate(string)
write(*, *) string, "X"
```
```bash
$ ../build-release/bin/flang-new test.f90
$ ./a.out
Wed Nov 15 16:59:13 2023 X
```
The length value is hardcoded, because:
```c++
// Day Mon dd hh:mm:ss yyyy\n\0 is 26 characters, e.g.
// Tue May 26 21:51:03 2015\n\0
```
---------
Co-authored-by: Yi Wu <yiwu02@wdev-yiwu02.arm.com>
This patch add support of intrinsics Fortran 2008 EXECUTE_COMMAND_LINE.
The patch contains both the lowering and the runtime code and works on
both Windows and Linux. The patch contains a list of commits, to convey
the authorship and the history of changes. Some implementation specifics
or status has been added to `flang/docs/Intrinsics.md`.
I have provided a summary of the usage and the options required for the
`EXECUTE_COMMAND_LINE intrinsic`. The intrinsic supports both a
synchronous
(by default) and an asynchronous option.
| System | Mode | Implemention |
|---------|-------|---------------------------|
| Linux | Sync | std::system() |
| Windows | Sync | std::system() |
| Linux | Async | fork() |
| Windows | Async | CreateProcess |
Support for the SYSTEM GNU extension will be added in a separate PR.
Co-authored with @jeffhammond
---------
Signed-off-by: Jeff Hammond <jeff.science@gmail.com>
Co-authored-by: Jeff Hammond <jeff.science@gmail.com>
Co-authored-by: Yi Wu <yiwu02@wdev-yiwu02.arm.com>
When an input data-list has more items than can be read by a format from
the input record (e.g., "(4I5)" reading "1 2"), don't return false from
EditIntegerInput() just because nothing was read -- that will prevent
later items from being set to zero, as they should be. Return true
unless nothing was read and there is some kind of error pending.
Fixes llvm-error-tests/Fortran/gfortran/regression/pr478478.f90.
The I/O runtime's API allows -1 to be passed for a unit number in a
READ, WRITE, or PRINT statement, where it gets replaced by 5 or 6 as
appropriate. This turns out to have been a bad idea, as it prevents the
I/O runtime from detecting and reporting a program's invalid attempt to
use -1 as an I/O unit number. So just pass 5 or 6 as appropriate.
Fortran 2023 subclause 13.7.2.3.8 discusses input rounding only in the
context of decimal-to-binary conversion. There is no mention of rounding
for hexadecimal floating-point input conversion. At least one Fortran
compiler seems to have interpreted this silence as implying no rounding.
(Note that this is not the same thing as rounding to zero (RZ), which
would return +/-HUGE() for overflow.)
Nearly every Fortran compiler supports the extension of NAMELIST input
into a storage sequence identified by its initial scalar array element.
For example,
&GROUP A(1) = 1. 2. 3. /
should be processed as if the input had been
&GROUP A(1:) = 1. 2. 3. /
Fixes llvm-test-suite/Fortran/gfortran/regression/namelist_24.f90.
Shift the data from lower to higher order bits when memcpy the value in
the namelist in the big endian environment
---------
Co-authored-by: Mark Danial <mark.danial@ibm.com>
Co-authored-by: Kelvin Li <kli@ca.ibm.com>
The Fortran standard says that overflow input cases in some rounding
modes (RZ, RD, RU) should round to a "representable" number. Some
Fortran compilers interpret this to mean +/-HUGE(), some as +/-Inf.
Follow the precedent of gfortran and the Intel compilers.
If list-directed input contains a repeated item ("20*123.0") that is not
fully consumed by the READ statement's data item list, the end of that
READ statement was repositioning the input to the repeated value
("123.0"), leading to later confusion. Cancel the input item repetition
during EndIoStatement() processing to prevent this misbehavior.
Fixes llvm-test-suite/Fortran/gfortran/regression/list_read_4.f90.
When the result of NEAREST() has an exponent less than that of the
argument (e.g., NEAREST(1.,-1.) and NEAREST(-1.,1.)), the result was
wrong, because the increment value uses the result of SPACING() in terms
of the argument. Fix by just calling into the C runtime routine
std::nextafter().
When generalized numeric output editing of real data maps to Fw.d output
editing, either two or four trailing blanks are emitted depending on the
presence and value of 'e'. The code that detects field width overflow
didn't take these trailing blanks into account, and sometimes the field
width adjustment was producing an F0.d output edit descriptor (no fixed
field width). Fix by retaining the original field width, but requiring
it to also accommodate the trailing blanks.
Fixes llvm-test-suite/Fortran/gfortran/regression/fmt_g.f.
When FINDLOC() can't find its target value among the unmasked array
elements, it must return a zero result. Its implementation doesn't
sufficiently distinguish a zero result from a hit in an array with lower
bound(s) less than one. Fix by adding a flag to distinguish the case
with no hits from cases with hits.
Fixes llvm-test-suite/Fortran/gfortran/regression/findloc_6.f90.
It would surprise me if this case ever arose outside a couple of tests
in llvm-test-suite/Fortran/gfortran/regression (namely
cshift_large_1.f90 and eoshift_large_1.f90), but now at least those
tests will pass.
A zero 'd' digit count in EX output editing has a meaning that's
distinct from other numeric output editing descriptors, and I missed
this in my initial implementation of the feature. d==0 means that the
runtime should emit hexadecimal digits after the (hexa)decimal point
until all of the rest of them would be zero.
This patch enables more numeric (mod, sum, matmul, etc.) APIs,
and some others.
I added new macros to disable warnings about using C++ STD methods
like operators of std::complex, which do not have __device__ attribute.
This may probably result in unresolved references, if the header files
implementation relies on libstdc++. I will need to follow up on this.
Even after 13e2200fa426faffb62bdaf8b2f1f5699eee1511 (Solaris lacks
`femode_t`, too), the Solaris `flang` build is still broken:
```
/vol/llvm/src/llvm-project/local/flang/runtime/exceptions.cpp:87:5: error: static assertion failed due to requirement 'sizeof(fenv_t) <= sizeof(int) * 8': increase ieee_status_type size
87 | sizeof(fenv_t) <= sizeof(int) * _FORTRAN_RUNTIME_IEEE_FENV_T_EXTENT, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/vol/llvm/src/llvm-project/local/flang/runtime/exceptions.cpp:87:20: note: expression evaluates to '200 <= 32'
87 | sizeof(fenv_t) <= sizeof(int) * _FORTRAN_RUNTIME_IEEE_FENV_T_EXTENT, | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
This patch fixes this by removing the assertion.
Tested on `amd64-pc-solaris2.11` and `sparcv9-sun-solaris2.11`.
There was some confusion about units (bytes vs characters) in the
handling of the amount of input remaining in fixed-width formatted input
fields. Clarify that any variable or parameter counting "remaining"
space in a field in the I/O runtime is always in units of bytes, and
make it so where it wasn't.
Fixes the bug(s) in
llvm-test-suite/Fortran/gfortran/regression/char4_iunit_2.f03, although
the test still won't pass due to its dependence on gfortran's
list-directed output spacing.
The overflow check didn't work for a 27-digit octal field containing an
80-bit x87 extended precision real value. The count of bytes required
was too large because the leading digit (1) was assumed to require a
full three bits. And the actual transmission of the octal input digits
to the output buffer was incorrect, too.
Fixes llvm-test-suite/Fortran/gfortran/regression/boz_15.f90.
Most Fortran implementations support a READ statement after a WRITE
without repositioning on a sequential unit; it implies on ENDFILE and
then hits an EOF condition.
Fixes llvm-test-suite/Fortran/gfortran/regression/backspace_2.f.
… input
The current EOF detection method (IsAtEOF()) depends on comparing the
current record number with the record number of the endfile record, if
it is known, which it is for units that have been written and then
rewound for input. For formatted input, this is wrong in the case of a
unit written with in-band newline characters. Rather than scan output
data to count newlines, it's best to just organically determine EOF by
detecting a failed or short read(), as we would have done anyway had the
endfile record number not been known. (I considered resetting the
endfile record number at the point of a REWIND, but not all rewinds are
followed by input; it seems wiser to defer the resetting until an actual
READ takes place.)
Fixes llvm-test-suite/Fortran/gfortran/regression/backslash_2.f90
Lowering doesn't use it, and won't need it in the future; it emits
in-line code for conversions and for assignments to scalars, and uses
the general Assign() routine for arrays.
…was written
At the end of an internal output statement, The I/O runtime fills (the
remainder of) the current record with blanks if it's the only record or
if anything had been written to it. This turns out to be wrong in the
case of a format that ends with an explicit advance to the next record,
which needs to be cleared even if nothing has been written.
Fixes llvm-test-suite/Fortran/gfortran/regression/arrayio_1.f90.
After a non-advancing WRITE to a unit, ensure that any ENDFILE operation
(explicit or implicit) terminates the record. (All other Fortran
implementations do so except XLF.)
Fixes llvm-test-suite/Fortran/gfortran/regression/advance_6.f90.
A tricky case in Fw.d output editing is when the value needs to be
rounded either to a signed zero or away from zero to a power of ten
(1.0, 0.1, &c.). A bug report for LLVM on GitHub (#74274) exposed a bug
in this code in the case of Fw.0 editing where a value just over 0.5 was
rounded incorrectly to 0 rather than 1 when no fractional digits were
requested.
Rework that algorithm a little, ensuring that the initial
binary->decimal conversion produces at least one digit, and coping
correctly with the rounding of an exact 0.5 value for Fw.0 editing
(rounding it to the nearest even decimal, namely 0, following
near-universal compiler-dependent behavior in other Fortrans).
Fixes https://github.com/llvm/llvm-project/issues/74274.
The present implementation of defined formatted I/O is incorrect for
arrays in the data item list; it assumes that a DT defined format
descriptor (or list-directed/namelist instance) applies to all of the
elements in the array. The loop over the elements in the array is within
the DefinedFormattedIo() template function that handles defined
formatted I/O, not around its calls. This causes only one format list
edit descriptor to be used for the whole array, which is of course
wrong.
Invert this arrangment by performing the per-element looping in at the
top level in FormattedDerivedTypeIo() instead.
Defined unformatted I/O remains as it was.