When a formatted I/O READ statement processes a DT edit descriptor to call a
user-defined I/O subroutine to read a derived type data item, all of the
characters that that subroutine reads via child I/O count as charecters
read by an edit descriptor and should accumulate in the result returned
by a SIZE= item in the original READ statement's control list.
Differential Revision: https://reviews.llvm.org/D144234
My earlier misreading of the Fortran standards had convinced me that child I/O
-- meaning the use of user-defined subroutines via generic interfaces to implement
data transfer statements -- was not allowed to advance the current record in the
ultimate unit of the original (non-child parent) data transfer statement.
This turns out to be wrong, so forward AdvanceRecord() from ChildFormattedIoStatement<>
to its parent I/O statement rather than implementing it as a no-op.
Differential Revision: https://reviews.llvm.org/D144205
The runtime type information table generator was broken when dealing
with an extension derived type that didn't include a special generic
procedure binding for ASSIGNMENT(=) or user-defined I/O, but one of
whose ancestor types did. Ensure that the runtime derived type info
tables have complete subtables for all of these special bindings,
and respect any overrides that may have been defined.
Motivating example:
type parent
contains
procedure :: dtWrite => dtWrite1
generic :: write(formatted) => dtWrite
end type
type, extends(parent) :: extended
contains
procedure :: dtWrite => dtWrite2
end type
The runtime derived type information table for "extended" must include
a special generic procedure entry for "write(formatted)" that points
to "dtWrite2" even though "extend" has no generic procedure for
"write(formatted)".
Differential Revision: https://reviews.llvm.org/D144148
When the rhs is polymorphic and allocated during assignment, the
derivedType might have change from the one set in `toDerived`.
Use the one set in the addendum so it is always up to date.
This can happen in cases like the one shown below:
```
type :: t1
end type t1
type, extends(t1) :: t2
integer, allocatable :: i(:)
end type
subroutine assign(t)
class(t2), intent(in) :: t
class(t1), allocatable :: cp
cp = t
end subroutine
```
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D144171
When either descriptor argument to MayAlias() is not allocated, the
result must be false by definition, since the values of the extents
in the dimensional information may be uninitialized.
Differential Revision: https://reviews.llvm.org/D144134
During child I/O -- a call to a user-defined subroutine with a generic interface
to handle read and write operations on a specific derived type -- ensure that
any INQUIRE statement probing mutable modes like BLANK= will observe changes
that have been made to those modes via control edit descriptors like BN
while processing the original I/O statement's format.
Differential Revision: https://reviews.llvm.org/D144046
Detect and handle LHS/RHS aliasing when effecting intrinsic
assignments via the Assign() runtime function.
Also: don't apply special handling for allocatable LHS when calling
a user-defined type-bound ASSIGNMENT(=) generic procedure for a
polymorphic type, and refactor some code into utility functions to
make Assign() more comprehensible.
Differential Revision: https://reviews.llvm.org/D144026
In some remapping case the rank of the pointer is different
from the target one.
```
program remap
type :: p
integer :: a
end type t
type(p), target :: ta(10) = [ (t(i),i=1,10) ]
class(t), pointer :: p(:,:)
p(1:2,1:5) => ta
end
```
This patch updates the rank and the byte stride to fix such case.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D143566
Derived type from the MOLD was not carried over
to the newly allocated pointer or allocatable.
This may lead to wrong dynamic type when the pointer or allocatable
is polymorphic as shown in the example below:
```
type :: p1
integer :: a
end type
type, extends(p1) :: p2
integer :: b
end type
class(p1), pointer :: p(:)
allocate(p(5), MOLD=p2(1,2))
```
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D143525
First call to Assign is issuing finalization for the
LHS and its components. Avoid calling finalization for components
again when doing the component by component assignment.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D143187
The rank from the allocate object might be different from the rank
from the mold expression. Use the rank from the allocate object
when applying to mold so the bounds can be set correctly.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D143078
As Fortran 2018 9.7.1.2(7), the value of each element of allocate object
becomes the value of source when the allocate object is array and the
source is scalar.
Fix#60090.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D142112
This patch refactors the runtime support for GET_ENVIRONMENT_VARIABLE
to have a single entry point instead of 2. It also updates lowering
accordingly.
This makes it easier to handle dynamically optional arguments.
See also https://reviews.llvm.org/D118777
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D142489
This patch improves the error message when MOVE_ALLOC is passed the same
allocated allocatable as both the to and from arguments.
Differential Revision: https://reviews.llvm.org/D142899
Derived type default initialization was not taking the step into
consideration.
```
module dt_init
type p1
integer :: a
end type
type, extends(p1) :: p2
integer :: b = 10
end type
contains
subroutine init_dt(z)
class(p1), intent(out) :: z(:)
select type(z)
type is (p2)
print*,z
end select
end subroutine
end module
program test
use dt_init
type(p2) :: t(6) = [ p2(1,2),p2(3,4),p2(5,6),p2(7,8),p2(9,10),p2(11,12) ]
print*,t
call init_dt(t(::2))
print*,t
end program
```
Without the fix, the three first elements are initialized
```
1 2 3 4 5 6 7 8 9 10 11 12
1 10 5 10 9 10
1 10 3 10 5 10 7 8 9 10 11 12
```
Where it should be element number 1,3,5
```
1 2 3 4 5 6 7 8 9 10 11 12
1 10 5 10 9 10
1 10 3 4 5 10 7 8 9 10 11 12
```
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D142527
`PointerAssociateRemapping` expect a descriptor holding
a newRank x 2 array of int64. The previous lowering was wrong.
Adapt the lowering to fit the expectation of the runtime.
Use the `bounds` to get the rank.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D142487
When an unlimited polymorphic descriptor is establish for an intrinsic
type spec, the `PointerNullifyIntrinsic` or `AllocatableInitIntrinsic` runtime
function is called. These functions do not initialize an addendum with a derivedType.
When the deallocation on this descriptor is performed, the runtime should not
crash if the addendum is not present. This patch updates `PointerDeallocatePolymorphic`
and `AllocatableDeallocatePolymorphic` for this use case.
Depends on D141996
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D142010
This patch adds a move_alloc implementation to the flang runtime.
Most of the checks required by the standard for move_alloc are
done by semenatic analysis; these checks are not replicated here.
Differential Revision: https://reviews.llvm.org/D141286
Lower allocate statement with MOLD= to calls to the Fortran
runtime. PointerApplyMold and AllocatableApplyMold are called
depending on the object to be allocated.
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D141843
Currently, cmake gives errors that check_cxx_compiler_flag and append are
unknown when building the Decimal and runtime libraries standalone. Add
the appropriate include to resolve this.
Differential Revision: https://reviews.llvm.org/D141525
Support allocate statement with source in runtime version. The source
expression is evaluated only once for each allocate statement. When the
source expression has shape-spec, uses it for bounds. Otherwise, get
the bounds from the source expression. Get the length if the source
expression has deferred length parameter.
Reviewed By: clementval, jeanPerier
Differential Revision: https://reviews.llvm.org/D137812
As mentioned in section 7.3.2.3 note 7, The dynamic type of an unallocated
allocatable object or a disassociated pointer is the same as its declared type.
This patch adds two function to the runtime:
- `PointerDeallocatePolymorphic`
- `AllocatableDeallocatePolymorphic`
These two functions take a DerivedTypeDesc pointer of the declared type.
The lowering is updated accordingly to call these functions for polymorphic
and unlimited polyrmophic entities. For unlimited polymorphic entities, the
dynamic type is set to nullptr when the entity is on an unallocated or
disassociated state.
Reviewed By: PeteSteinfeld, klausler
Differential Revision: https://reviews.llvm.org/D141519
Add implementation and loweirng for the extends_type_of
intrinsic.
The standard mentions this: otherwise if the dynamic type of A or MOLD is
extensible, the result is true if and only if the dynamic type of A is an
extension type of the dynamic type of MOLD. Which could be interpreted that
`extends_type_of(a, a)` could be false since a type is not an extension of
itself. Gfortran result for this is `true` so the same behavior is applied
here as well.
Depends on D141364
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D141376
The test performed by same_type_as does not consider kind type
parameters. If an exact match is not found, the name of the
derived type is compared. The name in the runtime info does not include
the kind type parameters as it does in the mangled name.
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D141364
When building the flang runtime if LTO is enabled the archive file
contains LLVM IR rather than object code. Currently flang is not
LTO aware so cannot link this file to compiled Fortran code.
This patch disables LTO when building the flang runtime to avoid
this issue.
Differential Revision: https://reviews.llvm.org/D140016
The runtime implementation uses the recurrence relations
`J(n-1, x) = (2.0 / x) * n * J(n, x) - J(n+1, x)`
`Y(n+1, x) = (2.0 / x) * n * Y(n, x) - Y(n-1, x)`
(see https://dlmf.nist.gov/10.74.iv and https://dlmf.nist.gov/10.6.E1).
Although the standard requires that `N1` and `N2` in `BESSEL_JN(N1, N2, x)`
and `BESSEL_YN(N1, N2, x)` be non-negative, this is not checked in the
runtime functions. This is in keeping with some other compilers which also
return some results when `N1` and/or `N2` are negative.
The special case for `x == 0` is handled in different runtime functions
for each of `BESSEL_JN` and `BESSEL_YN`. The lowering code checks for this
case and inserts the checks and the appropriate runtime calls in FIR.
The existing tests for the two intrinsics was modified to keep the style
consistent with the additional lowering tests that were added.
Extend the descriptor creation function for components to allow
unlimited polymorphic components (CLASS(*)) and to also properly set
the attributes of the established descriptors.
Differential Revision: https://reviews.llvm.org/D140141
Exponentiation is lowered to either math::FPowI or Fortran runtime
call (in case of --math-runtime=precise).
MathToFuncs convertor will convert math::FPowI operations with
exponent width >32 to calls of outlined implementations and otherwise
will leave the operation to MathToLLVM convertor.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D139806
Rework the recursive I/O error check on I/O units so that
threads again hold a lock on a unit throughout an I/O statement.
Add an API to the runtime's Lock class implementation for pthreads
to allow detection of solf-deadlock without depending on EDEADLK
or recursive mutexes.
This should fix I/O from OpenMP threads.
Differential Revision: https://reviews.llvm.org/D139477
The implementation follows the pattern used in comparable intrinsics.
Change the runtime API for Norm2 so it does not expect a mask argument
since the Norm2 intrinsic does not accept a mask in Fortran.
Differential Revision: https://reviews.llvm.org/D138150
The code is iterating on the rank of the pointer to set the bounds.
If the rank is retrieved after the `pointer = target` it does not
reflect the actual rank of the pointer.
This could happen in code like the following:
```
type t1
integer :: a
end type
type(t), pointer :: p(:)
class(t), pointer :: q(:,:)
q(0:1,-2:2) => p(10:1:-1)
```
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D139327
The implementation follows the patterns established by the lowering of other
similar intrinsics.
In addition to the code for lowering, the DoTotalReduction template had to be
fixed to correctly break when signaled to do so by the accumulator function.
Differential Revision: https://reviews.llvm.org/D138140
Add a `ClassIs` function that takes a descriptor and a
type desc to implement the check needed by the CLASS IS type guard
in SELECT TYPE construct.
Since the kind type parameter are directly folded in the type itself
in Flang and the type descriptor is a global, the function just check
if the type descriptor address of the descriptor is equivalent to
the type descriptor address of the global. If not, it check in the
parents of the descriptor's type descriptor.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D138279
To accomplish this, this patch creates an optional list of environment
variable default values to be set by the runtime to allow directly using
the existing runtime implementation of FORT_CONVERT for I/O conversions.
This patch adds a cpowi function to the flang runtime, and switches
to using that function instead of pgmath for complex number to
integer power operations.
Differential Revision: https://reviews.llvm.org/D134889
The GNU extension intrinsic IARGC is equivalent to
COMMAND_ARGUMENT_COUNT, and the GETARG is similar to
GET_COMMAND_ARGUMENT, but with less arguments. Reuse the runtime of
COMMAND_ARGUMENT_COUNT and GET_COMMAND_ARGUMENT for IARGC and GETARG.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D133558
We used to have a big switch statement over the type categories and kinds
inside Minloc/Maxloc. After D133051 the switch grew bigger, and this
changed inlining decisions made by GCC (the build compiler). Some of the
simple methods stopped being inlined, and this caused slight performance
regression in Polyhedron/gas_dyn2. This change adds separate entries
for real/integer data types to let them be optimized separately.
Differential Revision: https://reviews.llvm.org/D135610
A namelist input item that is a derived type component reference
needs additional processing when the base item or the component
is an array. When both have rank > 0, the component reference
must of course be subscripted.
(Fixes https://gitlab-master.nvidia.com/fortran/f18-stage/-/issues/999, NAG test t/tz2.)
A namelist input item that is a derived type component reference
needs additional processing when the base item or the component
is an array. When both have rank > 0, the component reference
must of course be subscripted.
Differential Revision: https://reviews.llvm.org/D135218
NAMELIST input processing in the runtime support library treats an
end-of-file found while searching for the initial '&' character
as an error condition, but it really should be distinguishable.
Call SignalEnd() rather than SignalError().
Differential Revision: https://reviews.llvm.org/D135212
std::numeric_limits<__float128>::max/lowest return 0.0, so recreate
value of FLT128_MAX ourselves to avoid using quadmath.h's FLT128_MAX
that is currently causes warnings with GCC -Wpedantic.
Differential Revision: https://reviews.llvm.org/D134496
BytesFor() used to return KIND for the size, which is not always
correct, so I changed it to return the size of the actual CppType
corresponding to the given category and kind.
MinElemLen() used to calculate size incorrectly (e.g. CFI_type_extended_double
was sized 10, whereas it may occupy more bytes on a target), so I changed it
to call BytesFor().
Additional changes were needed to resolve new failures for transformational
intrinsics. These intrinsics used to work for not fully supported
data types (e.g. REAL(3)), but now stopped working because CppType
cannot be computed for those categories/kinds. The solution is to use
known element size from the source argument(s) for establishing
the destination descriptor - the element size is all that is needed
for transformational intrinsics to keep working.
Note that this does not help cases, where runtime still has to
compute the element size, e.g. when it creates descriptors for
components of derived types. If the component has unsupported
data type, BytesFor() will still fail. So these cases require
adding support for the missing types.
New regression unit test in Runtime/Transformational.cpp
demonstrates the case that will start working properly with
this commit.
Currently, the FORT_CONVERT environment variable has the highest priority when
setting the endianness conversion for unformatted files. In discussing the
appropriate priority for the fconvert option, convert specifiers were decided
to take highest priority.
This patch also initializes the open statement convert state to unknown
to disambiguate cases where the convert specifier was not provided from
cases where convert=native was set. This makes it possible to defer to the
environment setting where appropriate.
Differential Revision: https://reviews.llvm.org/D133237