In case a character component PDT length only depends on kind parameters,
fold it while instantiating the PDT. This is especially important if the
component has an initializer because later semantic phases (offset
computation or runtime type info generation) might get confused and
generate offset/type info that will lead to crashes in lowering.
Differential Revision: https://reviews.llvm.org/D122938
Previously, some semantic checks that are checking if an entity is an
allocatable were relying on the expression being a designator whose
last symbol has the allocatable attribute.
This is wrong since this was considering substrings and array sections of
allocatables as being allocatable. This is wrong (see NOTE 2 in
Fortran 2018 section 9.5.3.1).
Add evaluate::IsAllocatableDesignator to correctly test this.
Also add some semantic tests for ALLOCATED to test the newly added helper.
Note that ifort and nag are rejecting coindexed-named-object in
ALLOCATED (`allocated(coarray_scalar_alloc[2])`).
I think it is wrong given allocated argument is intent(in) as per
16.2.1 point 3.
So 15.5.2.6 point 4 regarding allocatable dummy is not violated (If the actual
argument is a coindexed object, the dummy argument shall have the INTENT (IN)
attribute.) and I think this is valid. gfortran accepts it.
The need for this helper was exposed in https://reviews.llvm.org/D122779.
Differential Revision: https://reviews.llvm.org/D122899
Co-authored-by: Peixin-Qiao <qiaopeixin@huawei.com>
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
Assignment semantics was coughing up bad errors and crashes for
intrinsic assignments to unlimited polymorphic entities while
looking for any (impossible) user defined ASSIGNMENT(=) generic
or intrinsic type conversion.
Differential Revision: https://reviews.llvm.org/D122440
To make it easier to find things that are not yet implemented, I'm changing the
messages that appear in the compiler's output to all have the string "not yet
implemented:".
These changes apply to files in the front end. I have another set of changes
to files in the lowering code.
Differential Revision: https://reviews.llvm.org/D122355
Similarly to LBOUND in https://reviews.llvm.org/D121488, UBOUND must
return zero for an empty dimension, no matter the specification
expression.
Add a GetUBOUND method to be used in expression rewrite that prevents
folding UBOUND to a bound specification expression if the extent is
not a compile time constant.
Fold the case where the extents is known to be zero (and also deal with
this case in LBOUND since we can and should to comply with constant
expression requirements).
Differential Revision: https://reviews.llvm.org/D122242
Name resolution was crashing while processing the ENTRY statement
due to a lack of special-case code necessary to handle the indirection
needed when the generic has the same name as the ENTRY.
Differential Revision: https://reviews.llvm.org/D122050
This patch adds translation from PFT to FIR for critical construct.
This is part of the upstreaming effort from the fir-dev branch in [1].
[1] https://github.com/flang-compiler/f18-llvm-project
Co-authored-by: kiranchandramohan <kiranchandramohan@gmail.com>
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D122218
This patch adds parser nodes for each indivudual section in sections
construct. This should help with the translation to FIR. `!$omp section`
was not recognized as a construct and hence needed special handling.
`OpenMPSectionsConstruct` contains a list of `OpenMPConstruct`. Each
such `OpenMPConstruct` wraps an `OpenMPSectionConstruct`
(section, not sections). An `OpenMPSectionConstruct` is a wrapper around
a `Block`.
Reviewed By: kiranchandramohan, peixin
Differential Revision: https://reviews.llvm.org/D121680
Interfaces which are internal to a procedure need to be included in
module files if (and only if) they are referenced in the interface of
the procedure. That is, they are needed if they are the interfaces of
dummy or return value procedures.
Fixes#53420
Differential Revision: https://reviews.llvm.org/D121738
The intrinsic module IEEE_ARITHMETIC must incorporate the public
names from the intrisic module IEEE_EXCEPTIONS. Rename IEEE_EXCEPTIONS
to __Fortran_ieee_exceptions so that it won't clash with the
nonintrinsic namespace, establish a new intrinic IEEE_EXCEPTIONS
module that USEs it, and add a USE to IEEE_ARITHMETIC.
Updated to use STREQUAL rather than ambiguous MATCHES in
the CMakeLists.txt file.
Differential Revision: https://reviews.llvm.org/D121490
LBOUND must return 1 for an empty dimension, no matter what
explicit expression might appear in a declaration or arrive in
a descriptor.
Differential Revision: https://reviews.llvm.org/D121488
The intrinsic module IEEE_ARITHMETIC must incorporate the public
names from the intrisic module IEEE_EXCEPTIONS. Rename IEEE_EXCEPTIONS
to __Fortran_ieee_exceptions so that it won't clash with the
nonintrinsic namespace, establish a new intrinic IEEE_EXCEPTIONS
module that USEs it, and add a USE to IEEE_ARITHMETIC.
Differential Revision: https://reviews.llvm.org/D121490
evaluate::IsPointerObject used to return true for pointer suboject like
`pointer(10)` while these object are not pointers. This prevented some
checks like 15.5.2.7 to be correctly enforced (e.g., it was possible to
pass `pointer(10)` to a non intent(in) dummy pointer).
After updating IsPointerObject behavior and adding a test for 15.5.2.7 in
call07.f90, a test in call03.f90 for 15.5.2.4(14) was failing.
It appeared the related semantics check was relying on IsPointerObject
to return true for `pointer(10)`. Adapt the code to detect pointer element
in another way.
While looking at the code, I also noticed that semantics was
rejecting `character(1)` pointer/assumed shape suboject when these are
allowed (the standard has a special case for character(1) in
15.5.2.4(14), and I verified that other compilers that enforce 15.5.2.4(14)
do accept this).
Differential Revision: https://reviews.llvm.org/D121377
Using recently established message severity codes, upgrade
non-fatal messages to usage and portability warnings as
appropriate.
Differential Revision: https://reviews.llvm.org/D121246
F18 presently has fatal and non-fatal diagnostic messages. We'd like
to make non-fatal warnings stand out better in the output of the compiler.
This will turn out to be a large change that affects many files.
This patch is just the first part. It converts a Boolean isFatal_ data
member of the message classes into a severity code, and defines four
of these codes (Error, Warning, Portability, and a catch-all Other).
Later patches will result from sweeping over the parser and semantics,
changing most non-fatal diagnostic messages into warnings and portability
notes.
Differential Revision: https://reviews.llvm.org/D121228
When a module uses a derived type that is shadowed by a generic
interface, the module file was missing a USE statement for the
name. Detect and handle this situation.
Differential Revision: https://reviews.llvm.org/D121160
When a structure constructor does not initialize an allocatable component,
ensure that the typed expression representation contains an explicit
NULL() for the component. Expression semantics already copies default
initialized expressions for nonallocatable components into structure
constructors. This change is expected to simplify lowering.
Differential Revision: https://reviews.llvm.org/D121162
After merging https://reviews.llvm.org/D120801, Flang no longer builds
with GCC 11:
```
../llvm-project/flang/lib/Semantics/runtime-type-info.cpp:385:22: error: variable ‘lenParam’ set but not used [-Werror=unused-but-set-variable]
385 | for (SymbolRef lenParam : *lenParameters) {
| ^~~~~~~~
```
I'm sending this without a review as a quick fix.
This patches modifies PDT runtime type info generation so that it is
easier to handle derived type descriptor in lowering. It changes three
aspects:
1. The symbol name suffix of runtime type info for PDT instantiation is
changed from a serial number unrelated to the types to an encoding of
the instantiated KIND parameters.
2. New runtime type info is not created for each instantiation of PDT without
KIND parameters (only length parameters). Instead, the runtime type
info of the type definition is always used. It is updated to contain
the component descriptions.
3. Runtime type info of PDT instantiation is now always generated in the
scope where the type is defined. If several PDT type instantiation
are made in different scope with the same kind parameters, they will
use the same runtime type info.
Rational of the change:
In lowering, derived type descriptors are not mapped when instantiating derived
type objects. They are mapped later when symbol knowledge is not available anymore.
This mapping is based on the FIR representation of derived types. For
PDT, the FIR type information does not allow deducing the instantiation
scope, it only allows retrieving the type name, the type _definition_
scope, and the kind parameter values. Therefore, in order to be able to
retrieve the derived type descriptor from a FIR type, the derived type
descriptor must be generated in the definition scope and must reflect
the kind parameters. This justifies the need for changes 1. and 3.
above (suffix and scope change). Changes 2. comes from the fact that
all runtime type info of type without kind parameters can be generated
from the type definition, and that because of the suffix change, the
symbol name for type definition and type instantiation are the same.
Although this change is first motivated by how lowering handles derived
types, I believe it is also an improvement from a functional point of
view since this change will allow reducing the number of generated
runtime type info for PDTs, since redundant information (different
instantiations with same kind parameters) will only be generated once.
Differential Revision: https://reviews.llvm.org/D120801
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
The symbol table, name resolution, and semantic checks for module
subprograms -- esp. for MODULE FUNCTION and MODULE SUBROUTINE, but
also MODULE PROCEDURE -- essentially assumed that the subprogram
would be defined in a submodule of the (sub)module containing its
interface. However, it is conforming to instead declare a module
subprogram in the *same* (sub)module as its interface, and we need
to handle that case.
Since this case involves two symbols in the same scope with the same
name, the symbol table details for subprograms have been extended
with a pointer to the original module interface, rather than relying
on searching in scopes.
Differential Revision: https://reviews.llvm.org/D120839
Name resolution was properly probing the table of unrestricted
specific intrinsics to find "abs", but failing to capture the
result type and save it in the created symbol table entry.
Differential Revision: https://reviews.llvm.org/D120749
An assumed-type actual argument that corresponds to an assumed-rank dummy
argument shall be assumed-shape or assumed-rank.
Differential Revision: https://reviews.llvm.org/D120750
Derived types with allocatable and pointer components cannot
be used in I/O data transfer statements unless they have defined
I/O procedures available (as type-bound or regular generics).
These cases are caught as errors by the I/O runtime library,
but it would be better if they were flagged during compilation.
(Address comment in review: don't use explicit name string lengths.)
Differential Revision: https://reviews.llvm.org/D120675
Track source location information when available for actual arguments
to procedure references, and use this information when checking constraints
on calls so that error messages refer to specific actual arguments
rather than to the entire call.
Differential Revision: https://reviews.llvm.org/D119849
Calls to C_F_POINTER() without the optional SHAPE= third argument
were failing to be recognized as proper calls to the intrinsic,
but the failure was not generating any error message. This led to
a crash in lowering, which rightfully expects a typed expression
to be associated with the call.
So (1) catch silent failures to convert CALL statements as internal
errors, as is done for expressions and assignment statements; and
(2) clean up C_F_POINTER intrinsic handling to cope with only two
arguments and to emit an error for a FPTR= argument with no type.
Differential Revision: https://reviews.llvm.org/D119847
EQUIVALENCE storage association of objects whose types are not
both default-kind numeric storage sequences, or not both default-kind
character storage sequences, are not standard conformant.
However, most Fortran compilers admit such usage, with warnings
in strict conformance mode. This patch allos EQUIVALENCE of objects
that have sequence types that are either identical, both numeric
sequences (of default kind or not), or both character sequences.
Non-sequence types, and sequences types that are not homogeneously
numeric or character, remain errors.
Differential Revision: https://reviews.llvm.org/D119848
When a pointer assignment with bounds remapping has a function
reference as its right-hand side, don't check for array conformance.
Differential Revision: https://reviews.llvm.org/D119845
Semantic analysis was emitting a bogus error message when a structure
constructor contains a monomorphic value for a (limited) polymorphic
component of a derived type. The type compatibility test was too
strict; this patch relaxes it a little to allow values that could
be assigned or passed to a variable or dummy argument with that type.
Also add some quotes to an error message that was sometimes confusing
without them, and remove a repeated space character from another.
Differential Revision: https://reviews.llvm.org/D119744
The predicate IsInitialDataTarget() was failing to return a correct true
result in the case of a reference to the intrinsic function NULL() with a
MOLD= argument. Fix, and improve tests for "NULL()" elsewhere in semantics,
checking for an attribute set by intrinsics.cpp rather than the actual name.
Differential Revision: https://reviews.llvm.org/D119452
While one cannot of course statically initialize an allocatable component
of an instance of a derived type, its mere presence should not prevent
DATA initialization of the other nonallocatable components. Semantics
was treating the existence of an allocatable component as a case of
"default initialization", which it is, but not one that should run
afoul of C877. Add another Boolean argument to IsInitialized() to allow
for a more nuanced test.
Differential Revision: https://reviews.llvm.org/D119449
Currently, code generation was creating weak symbols for derived type
descriptor global it could not find in the current compilation unit.
The rational is that:
- the derived type descriptors of external module derived types are
generated in the compilation unit that compiled the module so that
the type descriptor address is uniquely associated with the type.
- some types do not have derived type descriptors: the builtin derived
types used to create derived type descriptors. The runtime knows
about them and does not need them to accomplish the feat of
describing themselves. Hence, all unresolved derived type descriptors
in codegen cannot be assumed to be resolved at link time.
However, this caused immense debugging pain when, for some reasons, derived
type descriptor that should be generated were not. This caused random
runtime failures instead of a much cleaner link time failure.
Improve this situation by allowing codegen to detect the builtin derived
types that have no derived type descriptors and requiring the other
unresolved derived type descriptor to be resolved at link time.
Also make derived type descriptor constant data since this was a TODO
and makes the situation even cleaner. This requiring telling lowering
which compiler created symbols can be placed in read only memory. I
considered using PARAMETER, but I have mixed feeling using it since that
would cause the initializer expressions of derived type descriptor to
be invalid from a Fortran point of view since pointer targets cannot be
parameters. I do not want to start misusing Fortran attributes, even if
I think it is quite unlikely semantics would currently complain. I also
do not want to rely on the fact that all object symbols with the
CompilerCreated flags are currently constant data. This could easily
change in the future and cause runtime bugs if lowering rely on this
while the assumption is not loud and clear in semantics.
Instead, add a ReadOnly symbol flag to tell lowering that a compiler
generated symbol can be placed in read only memory.
Differential Revision: https://reviews.llvm.org/D119555
Device clause when it occurs with **target enter data** and **target exit data** must be declared with some non negative value. So some changes were made to evaluate the device clause argument to non negative value and throw the expected error when it takes negative value as argument.
Reviewed By: clementval
Differential Revision: https://reviews.llvm.org/D119141
It is generally an error when a USE-associated name clashes
with a name defined locally, but not in all cases; a generic
interface can be both USE-associated and locally defined.
This works, but not when there is also a local subprogram
with the same name, which is valid when that subprogram is
a specific of the local generic. A bogus error issues at
the point of the USE because name resolution will have already
defined a symbol for the local subprogram.
The solution is to collect the names of local generics when
creating the program tree, and then create their symbols as
well if their names are also local subprograms, prior to any
USE association processing.
Differential Revision: https://reviews.llvm.org/D119566
When a scope's symbol has characteriztics whose specification
expressions depend on other non-constant symbols in the same scope,
f18 rightfully emits an error. However, in the case of usage in
specification expressions involving host association, the program is not
invalid. This can arise, for example, in the case of an internal
function whose result's attributes use host-associated variables.
Differential Revision: https://reviews.llvm.org/D119565
Fortran allows forward references to derived types, including
function results that are typed in a prefix of a FUNCTION statement.
If a type is defined in the body of the function, a reference to
that type from a prefix on the FUNCTION statement must resolve to
the local symbol, even and especially when that type shadows one
from the host scope.
The solution is to defer the processing of that type until the
end of the function's specification part. But the language doesn't
allow for forward references to other names in the prefix, so defer
the processing of the type only when it is not an intrinsic type.
The data structures in name resolution that track this information
for functions needed to become a stack in order to make this work,
since functions can contain interfaces that are functions.
Differential Revision: https://reviews.llvm.org/D119448
Previously, when calling a procedure implicitly for which a global scope
procedure symbol with the same name existed, semantics resolved the
procedure name in the call to the global symbol without checking that
the symbol interface was compatible with the implicit interface of the
call.
This could cause expression rewrite and lowering to later badly process
the implicit call assuming a different result type or an explicit
interface. This could lead to lowering crash in case the actual argument
were incompatible with the dummies from the explicit interface.
Emit errors in the following problematic cases:
- If the result type from the symbol did not match the one from the
implicit interface.
- If the symbol requires an explicit interface.
This patch still allows calling an F77 like procedure with different
actual argument types than the one it was defined with because it is
correctly supported in lowering and is a feature in some program
(it is a pointer cast). The two cases that won't be accepted have
little chance to make much sense. Results returning ABIs may differ
depending on the return types, and function that requires explicit
interface usually requires descriptors or specific processing that
is incompatible with implicit interfaces.
Note that this patch is not making a deep analysis, and it will only
catch mistakes if a global symbol and an implicit interface are
involved. Cases where the user provided a conflicting explicit
interface would still require a pass after name resolution to study
conflicts more deeply. But these cases will not crash lowering or
trigger expression rewrite to do weird things.
Differential Revision: https://reviews.llvm.org/D119274
When a scope uses an explicit IMPORT statement to import a
symbol from the scope's host, it should not emit a bogus error
message later if that symbol is used in a specification construct.
The code that checks for imports being hidden by local declarations
was not allowing for the presence of host association (or USE)
indirection symbols in the local scope. Fix by using GetUltimate()
before checking for the hidden symbol.
Differential Revision: https://reviews.llvm.org/D118747
When constructing the representation for a component reference
to an inherited component, expression semantics make the parent
component references explicit in the DataRef; e.g., base%component
becomes base%parent%grandparent%component if component was
inheritance-associated through two levels. But expression semantics
was inserting references to the symbol table entries for the
intermediate types, not the symbols for the parent components in
the extended types. (We didn't notice the distinction until
recently because both symbols have the same name; this only
affects lowering.) Find and use the right symbols.
Differential Revision: https://reviews.llvm.org/D118746
For "USE, INTRINSIC", search only for intrinsic modules;
for "USE, NON_INTRINSIC", do not recognize intrinsic modules.
Allow modules of both kinds with the same name to be used in
the same source file (but not in the same scoping unit, a
constraint of the standard that is now enforced).
The symbol table's scope tree now has a single instance of
a scope with a new kind, IntrinsicModules, whose children are
the USE'd intrinsic modules (explicit or not). This separate
"top-level" scope is a child of the single global scope and
it allows both intrinsic and non-intrinsic modules of the same
name to exist in the symbol table. Intrinsic modules' scopes'
symbols now have the INTRINSIC attribute set.
The search path directories need to make a distinction between
regular directories and the one(s) that point(s) to intrinsic
modules. I allow for multiple intrinsic module directories in
the second search path, although only one is needed today.
Differential Revision: https://reviews.llvm.org/D118631
User-defined derived type I/O implementation subroutines and
generic interfaces may be USE-associated, but the code that builds
the type description table wasn't allowing for that possibility.
Add a call to GetUltimate() to cope.
Differential Revision: https://reviews.llvm.org/D117902
Consistent with previously documented policy, in which
BOZ literals are accepted in non-standard-conforming circumstances
where they can be converted to an unambiguous known numeric type,
allow BOZ literals to be passed as an actual argument in a reference
to a procedure whose explicit interface has a corresponding dummy
argument with a numeric type to which the BOZ literal may be
converted. Improve error messages associated with BOZ literal
actual arguments, too: don't emit multiple errors.
Differential Revision: https://reviews.llvm.org/D117698
When variable with the SAVE attribute appears in a pure subprogram,
emit a more specialized error message if the SAVE attribute was acquired
from static initialization.
Differential Revision: https://reviews.llvm.org/D117699