The Fortran standard committees passed an "interp" request at their June
2024 meetings that is distinct from nearly every other Fortran compiler
that I tried (6) in an an ambiguous case (parent component naming when
the base type has been renamed via USE association). Document this case
in flang/docs/Extensions.md as an intentional instance of
non-conformance chosen for portability and better usability.
This CDEFINED keyword extension to a language-binding-spec signifies
that static storage for an interoperable variable will be allocated
outside of Fortran, probably by a C/C++ external object definition.
…ILE dummies
There's language in the standard (F'2023 15.5.2.5 p21) disallowing an
actual argument with a vector subscript from associating with a dummy
argument with either the ASYNCHRONOUS or VOLATILE attributes. This is a
bug in the standard, as (1) these attributes are actually relevant only
over the scope of the called procedure, (2) they can be applied in
nested scopes (internal subprograms and BLOCK) within the called
procedure, and (3) can be implicit within the called procedure and its
nested scopes in the case of ASYNCHRONOUS as a side effect of using a
dummy argument in an asynchronous data transfer statement. So issue a
warning. This new warning about undefinable actual arguments being
associated with ASYNCHRONOUS and VOLATILE dummy arguments subsumes an
existing warning about passing a constant actual to a VOLATILE dummy.
Resolves https://github.com/llvm/llvm-project/issues/93600.
The standard requires that dummy arguments to PURE functions be
INTENT(IN) or VALUE, but PURE subroutines are allowed to have modifiable
dummy arguments. This makes it impossible to declare atomic operations
as PURE functions, which consequently makes such atomic operations
ineligible for use in parallel constructs and DO CONCURRENT.
This patch downgrades this error to a warning by default, which can be
seen with -pedantic & al. and remain an error with -Werror.
Most Fortran compilers accept "doubled operators" as a language
extension. This is the use of a unary '+' or '-' operator that is not
the first unparenthesized operator in an expression, as in 'x*-y'.
This compiler has implemented this extension, but in a way that's
different from other compilers' behavior. I interpreted the unary
'+'/'-' as a unary operator in the sense of C/C++, giving it a higher
priority than any binary (dyadic) operator.
All other compilers with this extension, however, give a unary '+'/'-' a
lower precedence than exponentiation ('**'), a binary operator that
C/C++ lacks. And this interpretation makes more sense for Fortran,
anyway, where the standard conforming '-x**y' must mean '-(x**y)'
already.
This patch makes 'x*-y**z' parse as 'x*-(y**z)', not 'x*(-y)**z)', and
adds a test to ensure that it does.
… with monomorphic dummy
The relevant standard requires (F'2023 15.5.2.6 p2) that when a pointer
or allocatable actual argument is associated with an
identically-attributed dummy argument, either both are polymorphic or
neither is. We already relax this requirement in the case of an
INTENT(IN) dummy argument, since a change of type cannot occur. Further,
like other compilers do, we can also relax this requirement in the case
of a limited polymorphic actual argument being associated with a
monomorphic dummy, as our implementation always passes a reference to
the actual descriptor, where any change of type that occurs during the
call due to reallocation will be properly recorded.
A derived type that meets (most of) the requirements of an interoperable
type but doesn't actually have the BIND(C) attribute can be accepted as
an interoperable type, with optional warnings.
Fortran has an ambiguously defined rule about the typing of index
variables of implied DO loops in DATA statements and array constructors
that omit an explicit type specification. Such indices have the type
that they would have "if they were variables" in the innermost enclosing
scope. Although this could, and perhaps should, be read to mean that
implicit typing rules active in that innermost enclosing scope should be
applied, every other Fortran compiler interprets that language to mean
that if there is a type declaration for that name that is visible from
the enclosing scope, it is applied, and it is an error if that type is
not integer.
Fixes https://github.com/llvm/llvm-project/issues/91053.
Flang also supports non-scalar logical dummy argument with a different
KIND from C_BOOL to a bind(c) routine as well as a component in a
bind(c) derived type. Update the document.
```
subroutine sub(arg)
logical(4) :: arg(4)
end
```
```
type dt
logical(4) :: comp
end type
end
```
…nt arguments
Arguments to the intrinsic functions MAX and MIN after the first two are
optional. When these actual arguments might not be present at run time,
emit a compilation time error if they require data conversion (a
non-standard but nearly universal language extension); such a conversion
would crash if the argument was absent.
Other compilers either disallow data conversions entirely on MAX/MIN or
crash at run time if a converted argument is absent.
Fixes https://github.com/llvm/llvm-project/issues/87046.
Allocatable components of structure constructors were not deallocated.
Deallocate them without calling final subroutines.
This was already properly done for array constructors.
The specific intrinsic function INDEX should work as a PROCEDURE
interface in the declaration of a procedure pointer or dummy procedure,
and it should be compatible with a user-defined interface.
Fixes https://github.com/llvm/llvm-project/issues/82397.
The standard states that data objects involved in an asynchronous data
transfer statement gain the ASYNCHRONOUS attribute implicitly in the
surrounding subprogram or BLOCK scope. This attribute affects the checks
in call semantics, as an ASYNCHRONOUS actual object associated with an
ASYNCHRONOUS dummy argument must not require data copies in or out.
(Most compilers don't implement implied ASYNCHRONOUS attributes
correctly; XLF gets these right, and GNU is close.)
When a generic procedure interface, either declared or the result of
merging two use-associated generics, has two specific procedures
that are not distinguishable according to the rules in F'2023
subclause 15.4.3.4.5, emit a portability warning rather than a
hard error message. The rules in that subclause are not adequate
to detect pairs of specific procedures that admit an ambiguous
reference, as demonstrated by a case that arose in pFUnit. Further,
these distinguishability checks, even if sufficient to the task
of detecting pairs of specifics capable of ambiguous references,
should only apply to pairs where *every* reference would have to
be ambiguous -- and this can and is validated at every reference
anyway. Last, only XLF enforces these incomplete and needless
distinguishability rules -- every other compiler seems to just
check that each procedure reference resolves to exactly one
specific procedure.
If the standard were to complete lose subclause 15.4.3.4.5 and
its related note (C.11.6) -- which admits that the rules are
incomplete! -- and simply require that each generic procedure
reference resolve unambiguously to exactly one specific, nobody
would miss them. This patch changes this compiler to give them
lip service when requested, but they are now otherwise ignored.
Added support for COSD and SIND. This is quick fix. ATAND, TAND, COSD
and SIND needs to be revisited to make it a runtime call. This patch has
code changes and test cases.
Using the VALUE attribute for assumed-length CHARACTER dummy arguments
became standard in F'2008 but still lacks widespread implementation;
emit a portability warning when they are enabled.
Resolves llvm-test-suite/Fortran/gfortran/regression/value_5.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.
There are some very odd (even for Fortran) rules in F'2023 subclause
19.4 (paras 6 & 8) pertaining to the index variables of FORALL and DO
CONCURRENT constructs/statements, and they are not currently implemented
correctly.
Although these index variables are construct entities, they have
restrictions in the standard that would essentially allow them to also
be variables in their enclosing scopes. If their names are present in
the enclosing scope, and the construct does not have an explicit type
specification for its indices, then the names in the enclosing scope
must either be scalar variables or COMMON blocks, and their type must be
integer.
Reimplement these restrictions largely with portability warnings rather
than hard errors. Retain the semantic interpretation that the type of an
untyped index variable be taken from the type of a variable of the same
name in the enclosing scope, if it exists, although that bit of the
standard could be interpreted otherwise.
Fixes https://github.com/llvm/llvm-project/issues/76978.
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).
…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.
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.
The compiler doesn't USE-associate names of intrinsic procedures from
modules (in the absence of ONLY:), so that the associating scope doesn't
get populated with names of intrinsics that were used only in
declarations (e.g., SELECTED_REAL_KIND). A recent bug report (below)
shows that we should modify that policy in the case of names that appear
in explicit INTRINSIC attribute statements. The behaviors of other
Fortran compilers are not consistent and the requirements of the
standard are not clear; this fix follows the precedent set by gfortran
and nvfortran.
Fixes https://github.com/llvm/llvm-project/issues/72084.
Fortran free form line continuation with '&' works with this compiler
even across the end of an included source file, as it does with most
other Fortran compilers. This extension should be documented.
A NULL() pointer without MOLD= cannot be allowed to be associated with
an assumed-rank dummy argument, as its rank is not well-defined and
neither the RANK() intrinsic function or the SELECT RANK construct will
work in the callee.
As an extension, accept the redundant use of the CONTIGUOUS attribute
when applied to scalars and to simply contiguous objects, with a
portability warning.
As is already supported as a common extension for intrinsic functions
like DIM, allow distinct kinds of integer actual arguments to the
MIL-STD bit intrinsic functions IAND, IEOR, and IOR, with the kind of
the result being the largest of the kinds of the operands. (Though one
could make a case that IAND should return the smallest kind of its
operands, that's not what other compilers do.)
Fortran allows forward references to type names, which can lead to
ambiguity when coupled with host association, as in:
module m
type ambiguous; integer n; end type
contains
subroutine s
type(ambiguous), pointer :: variable
type t
type(ambiguous), pointer :: component
end type
type ambiguous; real x; end type
end
end
Some other compilers resolve to a host association, some resolve to a
forward reference. This compiler will now emit an error.
Follow up up of https://github.com/llvm/llvm-project/pull/67693
- Zero initialize uninitialized components of saved derived type entity
with a default initial value.
- Zero initialize uninitialized storage of common blocks with a member
with an initial value.
- Zero initialized uninitialized saved equivalence
This removes all the cases where fir.global are created with an initial
value that results in an undef in LLVM for part of the global, leading
in surprising LLVM optimizations at -O2 for Fortran folks that expects
there saved variables to be zero initialized if there is no explicit or
default initial value.
This is not standard but is vastly expected by existing code.
This was implemented by https://reviews.llvm.org/D149877 for simple
scalars, but MLIR lacked a generic way to deal with aggregate types
(arrays and derived type).
Support was recently added in
https://github.com/llvm/llvm-project/pull/65508. Leverage it to zero
initialize all types.
…mmy argument
Several compilers accept a null pointer (with or without a MOLD=) as an
actual argument for association with an INTENT(IN) allocatable dummy
argument. At runtime, the allocatable dummy argument appears to be in
the unallocated state. This seems useful, unambiguous, unlikely to
invalidate conforming code, and works with Intel, NAG, & XLF, so it
should be supported with an optional portability warning in this
compiler as well.
The Fortran standards require (F'2023 C745) that a derived type with the
SEQUENCE attribute have at least one component. No Fortran compiler
actually enforces this constraint. Accept this usage with a warning.
At least one other Fortran compiler supports the use of unrestricted intrinsic
functions as specific procedures in generic interfaces, and the usage seems
to be both useful and unambiguous. Support it with a portability warning.
Fixes llvm-test-suite/Fortran/gfortran/regression/pr95500.f90.
Differential Revision: https://reviews.llvm.org/D157333
A quotation mark can appear in a Fortran character literal by doubling
it; for example, PRINT *, "'""'" prints '"'. When those doubled
quotation marks are split by a free form line continuation, the
continuation line should have an ampersand before the second quotation
mark. But most compilers, including this one, allow the second
quotation mark to appear as the first character on the continuation
line, too.
So this works:
print *, "'"&
"'"
but it really should be written as:
print *, "'"&
&"'"
Emit a portability warning and document that we support this near-universal
extension.
Differential Revision: https://reviews.llvm.org/D155973
This implements the tand intrinsic by performing a multiplication
by pi/180 to the argument before calling tan inline.
This is a commonly provided extension that is used by OpenRadioss
Differential Revision: https://reviews.llvm.org/D154614
Fix some problems with INCLUDE line recognition pointed out by some
recently-added tests to the LLVM test suite.
Differential Revision: https://reviews.llvm.org/D155497
It is not standard conforming under IMPLICIT NONE(TYPE) for a name to
appear in a DATA statement prior to its explicit type declaration,
but it is benign, supported in other compilers, and attested in real
applications. Support it with an optional portability warning.
Fixes GitHub LLVM bug https://github.com/llvm/llvm-project/issues/63783.
OPEN statements can be used to change some, but not all, attributes
of units that have already been opened. The I/O runtime library
wasn't allowing ENCODING= to be changed. Every other Fortran compiler
permits this usage, and it's safe and useful, so allow it.
(Otherwise there's no good way to ensure that the preconnected
unit 6 is in UTF-8 mode.)
Differential Revision: https://reviews.llvm.org/D154379
We intentionally process NAMELIST groups in a scope after having
resolved all of the names in that scope. This means that a name
whose first appearance in a scope is in the NAMELIST group resolves
to a local object, if any, rather than to any host associated object.
The standard is unclear on this point, and there is no clear
precedent in other compilers.
This patch doesn't implement this choice -- that was done long ago --
but just documents the behavior in Extensions.md.
Differential Revision: https://reviews.llvm.org/D154375
Apply the default PUBLIC/PRIVATE accessibility of a module to its symbols
a second time after it is known that all symbols, including implicitly typed
names from NAMELIST groups and specification expressions in module subprograms,
have been created in its scope.
Fixes https://github.com/llvm/llvm-project/issues/62598.
Differential Revision: https://reviews.llvm.org/D150307
Instead of filling uninitialized global variables with "undef",
initialize them with 0. Only for Integer, Float or Logical type
variables. Complex, user defined data structures, arrays, etc
are not supported at this point.
This patch fixes the main problem of
https://github.com/llvm/llvm-project/issues/62432
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D149877