PR #101009 exposed a semantic check issue with OPTIONAL dummy
arguments.
Another issue occurred when using %{re,im,len,kind}, as these also
need to be skipped when handling variables with implicitly defined
DSAs.
These issues were found by Fujitsu testsuite.
When the result of a function never appears in a variable definition
context, emit a warning.
If the function has multiple result variables due to alternate ENTRY
statements, any definition will suffice.
The implementation of this check is tied to the general variable
definability checking utility in semantics. Every variable definition
context uses it to ensure that no undefinable variable is being defined.
A set of defined variables is maintained in the SemanticsContext and,
when the warning is enabled and no fatal error has been reported, the
scope tree is traversed and all the function subprograms' results are
tested for membership in that set.
f18 current emits an error when an assignment is made to an array
section with a vector subscript, and the array is finalized with a
non-elemental final subroutine. Some other compilers emit this error
because (I think) they want variables to only be finalized in place, not
by a subroutine call involving copy-in & copy-out of the finalized
elements.
Since many other Fortran compilers can handle this case, and there's
nothing in the standards to preclude it, let's downgrade this error
message to a portability warning.
This patch got complicated because the API for the WhyNotDefinable()
utility routine was such that it would return a message only in error
cases, and there was no provision for returning non-fatal messages. It
now returns either nothing, a fatal message, or a non-fatal warning
message, and all of its call sites have been modified to cope.
SIZEOF and C_SIZEOF were broken for assumed-ranks because
`TypeAndShape::MeasureSizeInBytes` behaved as a scalar because the
`TypeAndShape::shape_` member was the same for scalar and assumed-ranks.
The easy fix would have been to add special handling in
`MeasureSizeInBytes` for assumed-ranks using the TypeAndShape
attributes, but I think this solution would leave `TypeAndShape::shape_`
manipulation fragile to future developers. Hence, I went for the
solution that turn shape_ into a `std::optional<Shape>`.
flang/test/Semantics/call40.f90 was failing on Darwin:
actual at 27: VAL or REF are not allowed for dummy argument 'a='
that must be passed by means of a descriptor
expect at 27: %VAL or %REF are not allowed for dummy argument 'a='
that must be passed by means of a descriptor
When messages.Say() is called with more arguments than just the
fixed text message, the message is treated as a format string,
passed to vsnprintf. Therefore, the '%' chars in it must be
escaped.
Note that no conversion happens when there is only a fixed text
message. Escaping '%' in this case causes "%%" to be outputted.
This can be confusing for someone expecting printf-like behavior.
Processing these text messages with snprintf could solve this,
as a future improvement.
Nothing in the standard actually prevents TARGET from being an
assumed-rank if the POINTER is. The only rank related constraints says:
"POINTER is not assumed-rank, TARGET shall have the same rank as
POINTER.".
…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.
In accordance with other compilers, don't require that a %REF() actual
argument be a modifiable variable. And move the %REF/%VAL semantic
checks to Semantics/check-call.cpp, where one would expect to find them.
Fixes https://github.com/llvm/llvm-project/issues/93489.
A NULL(without MOLD=) actual argument can be associated with an OPTIONAL
assumed-rank non-allocatable non-pointer dummy argument; it simply
signifies that the corresponding actual argument is absent, and thus
none of its dynamic attributes, including rank, are meaningful.
… 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.
…Warn()
Many warning messages were being emitted unconditionally. Ensure that
all warnings are conditional on a true result from a call to
common::LanguageFeatureControl::ShouldWarn() so that it is easy for a
driver to disable them all, or, in the future, to provide per-warning
control over them.
This patch updates the compatibility checks for CUDA attribute iin
preparation to implement the matching rules described in section 3.2.3.
We this patch the compiler will still emit an error when there is
multiple specific procedures that matches since the matching distances
is not yet implemented. This will be done in a separate patch.
https://docs.nvidia.com/hpc-sdk/archive/24.3/compilers/cuda-fortran-prog-guide/index.html#cfref-var-attr-unified-data
gpu=unified and gpu=managed are not part of this patch since these
options are not recognized by flang yet.
When the interface of a procedure is implicit at the point of call,
don't perform actual argument type conversion to the types of the dummy
arguments. This was inadvertently taking place in a case where the
procedure has an implicit interface but was also defined in the same
source file, so that its characteristics were known.
When the characteristics of a procedure depend on a procedure that
hasn't yet been defined, the compiler currently emits an unconditional
error message. This includes the case of a procedure whose
characteristics depend, perhaps indirectly, on itself. However, in the
case where the characteristics of a procedure are needed to resolve a
generic, we should not emit an error for a hitherto undefined procedure
-- either the call will resolve to another specific procedure, in which
case the error is spurious, or it won't, and then an error will issue
anyway.
Fixes https://github.com/llvm/llvm-project/issues/88677.
A recent patch added an error message for whole optional dummy argument
usage as optional arguments (third or later) to MAX and MIN when those
names required type conversion, since that conversion only works when
the optional arguments are present. This check shouldn't care about
character lengths. Make it so.
…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.
Supports the REDUCE() transformational intrinsic function of Fortran
(see F'2023 16.9.173) in a manner similar to the existing support for
SUM(), PRODUCT(), &c. There are APIs for total reductions to scalar
results, and APIs for partial reductions that reduce the rank of the
argument by one.
This implementation requires more functions than other reductions
because the various possible types of the user-supplied OPERATION=
function need to be elaborated.
Once the basic API in reduce.h has been approved, later patches will
implement lowering.
REDUCE() is primarily for completeness, not portability; only one other
Fortran compiler implements this F'2018 feature today, and only some
types work correctly with it.
When a Hollerith actual argument is associated with an unlimited
polymorphic dummy argument, it's treated as if it were CHARACTER. Some
other compilers treat it as if it had been BOZ, so emit a portability
warning.
Resolves https://github.com/llvm/llvm-project/issues/83548.
…istinguishing characteristic
We note whether a procedure's interface is explicit or implicit as an
attribute of its characteristics, so that other semantics can be checked
appropriately, but this internal attribute should not be used as a
distinguishing characteristic in itself.
Fixes https://github.com/llvm/llvm-project/issues/81876.
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.)
The argument to the PRESENT() intrinsic function must be the name of a a
whole OPTIONAL dummy argument.
Fixes llvm-test-suite/Fortran/gfortran/regression/present_1.f90.
The checking of calls to the intrinsic subroutine MOVE_ALLOC is not
insisting that its first two arguments be whole allocatable variables or
components. Fix, move the code into check-calls.cpp (a better home for
such things), and clean up the tests.
Fixes https://github.com/llvm/llvm-project/issues/77230.
…n actual argument is contiguous
When an element of a contiguous pointer array or assumed-shape array is
associated as an actual argument with an assumed-size dummy array, don't
flag the usage as an error.
…arrays
When comparing dummy array extents, cope with references to symbols
better (including references to other dummy arguments), and emit
warnings in dubious cases that are not equivalent but not provably
incompatible.
Move the code to check the arguments of references to the intrinsic
function REDUCE() into Semantics/check-calls.cpp, and add checks for
several requirements from the standard that weren't yet caught.
Before emitting a warning message, code should check that the usage in
question should be diagnosed by calling ShouldWarn(). A fair number of
sites in the code do not, and can emit portability warnings
unconditionally, which can confuse a user that hasn't asked for them
(-pedantic) and isn't terribly concerned about portability *to* other
compilers.
Add calls to ShouldWarn() or IsEnabled() around messages that need them,
and add -pedantic to tests that now require it to test their portability
messages, and add more expected message lines to those tests when
-pedantic causes other diagnostics to fire.
During function-like macro expansion in a standard C/C++ preprocessor,
the macro being expanded is disabled from recursive macro expansion. The
implementation in this compiler's preprocessor, however, was too broad;
the macro expansion needs to be disabled for the "rescanning" phase
only, not for actual argument expansion.
(Also corrects an obsolete comment elsewhere that was noticed during
reduction of an original test case.)
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.
…forwarded to CONTIGUOUS dummy
No object with the ASYNCHRONOUS or VOLATILE attribute can go through the
copy-in/copy-out protocol necessary for argument association with a
contiguous dummy array argument. The check for this constraint missed
the case of an assumed-rank array without an explicit CONTIGUOUS
attribute being forwarded on to a CONTIGUOUS dummy argument.
Semantics is emitting an error when an actual argument to a procedure
that has an implicit interface has a polymorphic type. This is too
general; while TYPE(*) and CLASS(*) unlimited polymorphic items require
the presence of an explicit procedure interface, CLASS(T) data can be
passed over an implicit interface to a procedure expecting a
corresponding dummy argument with TYPE(T), so long as T is not
parameterized.
(Only XLF handles this usage correctly among other Fortran compilers.)
(Making this work in the case of an actual CLASS(T) array may well
require additional changes in lowering to copy data to/from a temporary
buffer to ensure contiguity when the actual type of the array is an
extension of T.)
…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.
A NULL() pointer is an acceptable actual argument for association with
an (absent) optional allocatable dummy argument. Semantics was
unconditionally emitting an error that the actual argument is not
allocatable.
The POINTER= and TARGET= arguments to the intrinsic function
ASSOCIATED() can be the results of references to functions that return
object pointers or procedure pointers. NULL() was working well but not
program-defined pointer-valued functions. Correct the validation of
ASSOCIATED() and extend the infrastructure used to detect and
characterize procedures and pointers.
Unlike other executable constructs with associating selectors, the
selector of a SELECT RANK construct can have the ALLOCATABLE or POINTER
attribute, and will work as an allocatable or object pointer within
each rank case, so long as there is no RANK(*) case.
Getting this right exposed a correctness risk with the popular
predicate IsAllocatableOrPointer() -- it will be true for procedure
pointers as well as object pointers, and in many contexts, a procedure
pointer should not be acceptable. So this patch adds the new predicate
IsAllocatableOrObjectPointer(), and updates some call sites of the original
function to use the new one.
Differential Revision: https://reviews.llvm.org/D159043
This patch enables logical expressions to be used as arguments when the
default logical kind is changed (e.g. using -fdefault-integer-8) by
converting the type of the logical expression argument to the type of
the dummy argument in the function.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D157600
The TARGET= argument to the intrinsic function ASSOCIATED() must be
a valid target for the POINTER= argument, but we are missing some
cases, such as parenthesized expressions. Add more checking, and
restructure the logic a bit to make the case analysis structure
more clear.
Fixes llvm-test-suite/Fortran/gfortran/regression/associated_target_1.f90.
Differential Revision: https://reviews.llvm.org/D157341
Check for cases of storage sequence association in which an element or
substring is an actual argument associated with a dummy argument array
that can be detected as being larger than the remaining elements or characters
in the actual argument's storage sequence.
Differential Revision: https://reviews.llvm.org/D156757
This patch includes the a subset of MMA intrinsics that are included in
the mma intrinsic module:
mma_assemble_acc
mma_assemble_pair
mma_build_acc
mma_disassemble_acc
mma_disassemble_pair
Submit on behalf of Daniel Chen <cdchen@ca.ibm.com>
Differential Revision: https://reviews.llvm.org/D155725
A dummy argument with an assumed (*) character length or derived type parameter
value specification needs to be associated with an actual argument that can
supply a value for it, so make sure that a NULL without a MOLD= is not being
passed.
Differential Revision: https://reviews.llvm.org/D155971