…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.)
Runtime derived type info contains information to tell the runtime if
some argument in a user defined assignment must be passed with a
descriptor or not. This information was not properly build, it would
tell the runtime that TARGET argument must be passed via descriptor,
which is incorrect.
Share the logic between lowering and runtime info generation to
determine if an argument must be passed by descriptor or not.
A recent patch to allow pFUnit to compile softened the diagnostic about
indistinguishable specific procedures to a portability warning. It turns
out that this was overkill -- for specific procedures containing no
optional or unlimited polymorphic dummy data arguments, a diagnosis of
"indistinguishable" can still be a hard error.
So adjust the analysis to be tri-state: two procedures are either
definitely distinguishable, definitely indistinguishable without
optionals or unlimited polymorphics, or indeterminate. Emit errors as
before for the definitely indistinguishable cases; continue to emit
portability warnings for the indeterminate cases.
When this patch is merged, all but one of the dozen or so tests that I
disabled in llvm-test-suite can be re-enabled.
In
CALL FOO
PRINT *, ABS(FOO)
we currently resolve the first FOO to a global external subprogram, but
then the second FOO is treated as an implicitly typed local variable.
This happens because the name FOO is not present in the local scope.
Fix by adding FOO to the local scope using a place-holding
HostAssocDetails symbol whose existence prevents the creation of another
FOO in the local scope. The symbol stored in the parser::Name parse tree
nodes or used in typed expressions will all continue to point to the
global external subprogram.
Resolves llvm-test-suite/Fortran/gfortran/regression/pr71859.f90.
Recognize Cray pointees as such when they are declared as assumed size
arrays, and don't emit a bogus error message about implied shape arrays.
Fixes https://github.com/llvm/llvm-project/issues/77330.
…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.
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.)
When a separate module function's definition has a redundant interface
-- it's defined with MODULE FUNCTION, not MODULE PROCEDURE -- the check
for result type equivalence needs to allow for character lengths that
are the results of specification expressions. At present,
identical-looking length specification expression don't compare equal,
since they can refer to distinct dummy argument symbols. Ensure just
that they are both constant or not, and if constant, that the lengths
have the same value.
When a procedure with an implicit interface is called from two call
sites with distinct argument types, we emit a warning. This can lead to
a lot of output when the actual argument types are differing-length
character, and the warnings are less important since the procedure may
well have been defined with assumed-length character dummy arguments. So
let cases like CALL MYERROR('ab'); CALL MYERROR('abc') slide by without
a warning.
15.6.2.6 point 11/12/13 tells that entries do inherit the
RECURSIVE/PURE/ELEMENTAL aspects from the main entry, but nothing as
such is said for BIND(C). It seems each entry can independently have
BIND(C) or not.
Update characterization to not propagate this info in-between entries.
Add a lowering test for a tricky case of the character return where the
return ABI is different for the result with and without BIND(C), but the
results storage should be associated regardless of the ABI.
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.
Implements compatibility checking for initializers in procedure pointer
declarations. This work exposed some inconsistency in how ELEMENTAL
interfaces were handled and checked, from both unrestricted intrinsic
functions and others, and some refinements needed for function result
compatbility checking; these have also been ironed out. Some new
warnings are now emitted, and this affected a dozen or so tests.
Differential Revision: https://reviews.llvm.org/D159026
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
Add more checks to procedure compatibility testing for procedure pointer
assignments, actual procedure arguments, &c. Specifically, don't
allow corresponding dummy data objects to differ in their use
of polymorphism, assumed size arrays, or assumed shape arrays.
Differential Revision: https://reviews.llvm.org/D155974
Emit warnings when CHARACTER lengths or array sizes of actual
and dummy arguments mismatch in risky ways.
Differential Revision: https://reviews.llvm.org/D154370
Make __builtin_c_loc() into an intrinsic function and verify the
special semantic requirements on its actual arguments.
Differential Revision: https://reviews.llvm.org/D149988
Implement semantics for the IGNORE_TKR directive as it is interpreted
by the PGI / NVFORTRAN compiler.
Differential Revision: https://reviews.llvm.org/D148643
The compiler presently detects different dummy object array ranks;
extend the compatibility check to also note discrepancies in corresponding
constant dummy argument extents.
Differential Revision: https://reviews.llvm.org/D145748
When a global procedure has no explicit interface, emit warnings
when its references are inconsistent implicit procedure interfaces.
Differential Revision: https://reviews.llvm.org/D145097
The compiler currently ignores attributes for PASS dummy arguments that
are incompatible between a type-bound procedure in an extended type and
the binding of the same name that it overrides in an ancestor type,
if any. Strengthen this checking so that discrepancies between attributes
and intents are caught, and add some tests.
Differential Revision: https://reviews.llvm.org/D145110
The test for compatible function results needs to be nearly strict
equality of their types, not the usual actual/dummy type compatibility
test used in other situations. The exceptional case is that assumed
length CHARACTER function results are compatible with explicit length
results of the same kind. In particular, a function returning a
polymorphic pointer is not compatible with a function returning a
monomorphic pointer even of the same declared type.
Differential Revision: https://reviews.llvm.org/D145094
Fortran 2018 defines some flavors of dummy arguments to require exact
matching of character lengths between dummy and actual arguments;
these situations tend to be those in which the interface must be
explicit and a descriptor is involved: assumed shape, assumed rank,
allocatable, and pointer.
Fortran allows an actual argument in other cases to have a longer
length than the dummy argument; as a common extension, we support a
shorter actual argument as well by means of blank padding, but should
emit a warning.
Differential Revision: https://reviews.llvm.org/D143821
When character lengths are known at compilation time, report an error
when a data target with a known length does not match the explicit length
of a pointer that is being associated with it; see 10.2.2.3 paragraph 5.
Differential Revision: https://reviews.llvm.org/D142755
Semantics crashes when emitting runtime derived type information tables
for a type that has user-defined I/O procedures declared outside the
type with explicit INTERFACE blocks (as opposed to a GENERIC binding
within the type). This is due to the runtime table constructor
adding a table entry for each specific procedure of any explicit interface
of the right kind (e.g., READ(UNFORMATTED)) that it found, rather than
just the ones that pertain to the derived type in question. But
semantics also wasn't checking such interfaces for distinguishable
specific procedures, either.
Clean these up, improve the spelling of defined I/O procedure kinds
in error messages ("read(formatted)" rather than "READFORMATTED"),
and make error messages stemming from macro expansions only have
one "error:" prefix on the original message so that a new test
would work.
Differential Revision: https://reviews.llvm.org/D142769
Fix a subtle bug in procedure compatibility checking with base
derived types vs. their extensions to ensure that a procedure
expecting an extended type cannot be associated with a pointer
(or dummy procedure) to a procedure expecting a base type.
subroutine s1(base); ... subroutine s2(extended)
procedure(s1), pointer :: p
p => s2 ! <- must be caught as an error
Differential Revision: https://reviews.llvm.org/D142753
The ProcInterface structure is used only by ProcEntityDetails; it represents
what a program might have put in parentheses in a procedure-declaration-stmt,
either the name of a procedure interface or a declaration-type-spec.
If a procedure entity has an implicit interface, the function result
type (if any) can be kept in EntityDetails::type_, which already exists
and is currently redundant for ProcEntityDetails symbols.
All that is really needed is a nullable Symbol pointer in ProcEntityDetails
to point to the procedure's explicit interface, when it has one.
Also, catch the case where a procedure has an explicit interface
and a program attempts to also give it a type.
Differential Revision: https://reviews.llvm.org/D140134
When a character-valued function is passed as an actual argument, and both
the actual function and the dummy argument have explicit result lengths, take them
into account when testing for compatibility.
Differential Revision: https://reviews.llvm.org/D139129
Rework some recent changes to the ENUM_CLASS() macro so that
all of the construction of enumerator-to-name string mapping
data structures is again performed at compilation time.
Differential Revision: https://reviews.llvm.org/D137859
Some of the circumstances that require that a procedure have an
explicit interface at a point of call due to a characteristic of
a dummy argument apply to dummy procedures, too.
Differential Revision: https://reviews.llvm.org/D136994
When checking function interface compatibility for procedure pointer
assignment/initialization or actual/dummy procedure association, don't
emit a diagnositic about function result shape incompatibility unless
the interfaces differ in rank or have distinct constant extents on a
dimension. Function results whose dimensions are determined by dummy
arguments or host-associated variables are not necessarily incompatible.
Differential Revision: https://reviews.llvm.org/D132162
Procedure bindings with explicit interfaces don't work when the
interface is shadowed by a generic interface of the same name,
and can produce spurious semantic error messages. Extend the
characterization and checking code for such things, and the utility
functionns on which they depend, to dig through generics when they
occlude interface-defining subprograms. This is done on demand in
checking code, not once during name resolution, because the
procedures in question may also be forward-referenced.
Differential Revision: https://reviews.llvm.org/D131105
diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index e79f8ab6503e..0b03bf06eb73 100644
--- a/flang/include/flang/Semantics/symbol.h
Type-bound procedure bindings that specify intrinsic procedures as their
interfaces should not acquire the ELEMENTAL attribute from the purposes
of compatibility checking between inherited bindings and their overrides
in extended derived types.
Differential Revision: https://reviews.llvm.org/D131104
The predicate "CanBeCalledViaImplicitInterface()" was returning false for
restricted specific intrinsic functions (e.g., SIN) because their procedure
characteristics have the elemental attribute; this leads to a bogus semantic
error when one attempts to use them as proc-targets in procedure pointer
assignment statements when the left-hand side of the assignment is a procedure
pointer with an implicit interface. However, these restricted specific intrinsic
functions have always been allowed as special cases for such usage -- it is
as if they are elemental when it is necessary for them to be so, but not
when it's a problem.
Differential Revision: https://reviews.llvm.org/D130386
When a procedure pointer with no interface is associated with
an EXTERNAL name with no interface information, but it is later
inferred that the procedure pointer must be a subroutine because it
appears in a CALL statement, don't complain that the EXTERNAL name
is not also known to be a subroutine.
Subroutine vs. function errors are still caught in procedure pointer
assignment compatibility checking; this fix simply ensures that those
more nuanced tests are not overridded by the attribute set equality test.
Also, leave in some code for dumping the differing attributes in legitimate
error cases that was added in the coures of debugging the specific problem.
Differential Revision: https://reviews.llvm.org/D130385
Some procedure pointers and EXTERNAL procedures have neither
explicit interfaces nor result types; these procedures are obviously
not known to be functions, but they could be, so semantics must not
assume that they are necessarily subroutines. Refine the procedure
pointer / dummy procedure compatibility check to handle these more
ambiguous cases and not elicit inappropriate error messages.
Differential Revision: https://reviews.llvm.org/D129674
Create a TargetCharacteristics class to centralize the few items of
target specific information that are relevant to semantics. Use the
new class for all target queries, including derived type component layout
modeling.
Future work will initialize this class with target information
provided or forwarded by the drivers, and use it to fold layout-dependent
intrinsic functions like TRANSFER().
Differential Revision: https://reviews.llvm.org/D129018
Updates: Attempts to work around build issues on Windows.
For the program provided as the test case flang fired the following
error:
error: Semantic errors in main.f90
error: 'foo' is not a procedure
This change fixes the error by postponing handling of `UseErrorDetails`
from `CharacterizeProcedure` to a later stage.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D125791
Functions returning ALLOCATABLE or POINTER arrays have descriptor inquiries in
their results' shape expressions that won't compare equal. These functions
need only be checked for compatible ranks (& of course other characteristics).
Differential Revision: https://reviews.llvm.org/D125123
The following code causes the compiler to ICE in several places due to
lack of support of recursive procedure definitions through the function
result.
function foo() result(r)
procedure(foo), pointer :: r
end function foo
Adds flang/include/flang/Common/log2-visit.h, which defines
a Fortran::common::visit() template function that is a drop-in
replacement for std::visit(). Modifies most use sites in
the front-end and runtime to use common::visit().
The C++ standard mandates that std::visit() have O(1) execution
time, which forces implementations to build dispatch tables.
This new common::visit() is O(log2 N) in the number of alternatives
in a variant<>, but that N tends to be small and so this change
produces a fairly significant improvement in compiler build
memory requirements, a 5-10% improvement in compiler build time,
and a small improvement in compiler execution time.
Building with -DFLANG_USE_STD_VISIT causes common::visit()
to be an alias for std::visit().
Calls to common::visit() with multiple variant arguments
are referred to std::visit(), pending further work.
This change is enabled only for GCC builds with GCC >= 9;
an earlier attempt (D122441) ran into bugs in some versions of
clang and was reverted rather than simply disabled; and it is
not well tested with MSVC. In non-GCC and older GCC builds,
common::visit() is simply an alias for std::visit().
Adds flang/include/flang/Common/visit.h, which defines
a Fortran::common::visit() template function that is a drop-in
replacement for std::visit(). Modifies most use sites in
the front-end and runtime to use common::visit().
The C++ standard mandates that std::visit() have O(1) execution
time, which forces implementations to build dispatch tables.
This new common::visit() is O(log2 N) in the number of alternatives
in a variant<>, but that N tends to be small and so this change
produces a fairly significant improvement in compiler build
memory requirements, a 5-10% improvement in compiler build time,
and a small improvement in compiler execution time.
Building with -DFLANG_USE_STD_VISIT causes common::visit()
to be an alias for std::visit().
Calls to common::visit() with multiple variant arguments
are referred to std::visit(), pending further work.
Differential Revision: https://reviews.llvm.org/D122441
The "seenProcs" sets passed as arguments to the procedure and dummy
procedure characterization routines need to be passed by value so that
local updates to those sets do not become permanent. They are
presently passed by reference and that has led to bogus errors about
recursively defined procedures in testing.
(It might be faster to pass the sets by reference and undo those local
updates in these functions, but that's error-prone, and the performance
difference is not expected to be detectable in practice.)
Differential Revision: https://reviews.llvm.org/D122439
Add new IsCompatibleWith() member functions to many classes in evaluate::characteristics
that apply more nuanced compatibility checking for function results, dummy
arguments, and procedure interfaces than the previous tests for complete
equivalence. Use IsCompatibleWith() in semantics for call checking.
Differential Revision: https://reviews.llvm.org/D120844