Use derived type information tables to drive default component
initialization (when needed), component destruction, and calls to
final subroutines. Perform these operations automatically for
ALLOCATE()/DEALLOCATE() APIs for allocatables, automatics, and
pointers. Add APIs for use in lowering to perform these operations
for non-allocatable/automatic non-pointer variables.
Data pointer component initialization supports arbitrary constant
designators, a F'2008 feature, which may be a first for Fortran
implementations.
Differential Revision: https://reviews.llvm.org/D106297
The following semantic check is removed in OpenMP Version 5.0:
```
Taskloop simd construct restrictions: No reduction clause can be specified.
```
Also fix several typos.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D105874
Name resolution is always creating symbols with HostAssocDetails
for host variable names inside internal procedures. This helps lowering
identifying and dealing with such variables inside internal procedures.
However, the case where the variable appears in an ArrayRef mis-parsed
as a FunctionRef goes through a different name resolution path that did
not create such HostAssocDetails when needed. Pointer assignment RHS
are also skipping this path.
Add the logic to create HostAssocDetails for host symbols inisde internal
procedures that appear in mis-parsed ArrayRef or in pointer assignment RHS.
Differential Revision: https://reviews.llvm.org/D105464
With derived type description tables now available to the
runtime library, it is possible to implement the concept
of "child" I/O statements in the runtime and use them to
convert instances of derived type I/O data transfers into
calls to user-defined subroutines when they have been specified
for a type. (See Fortran 2018, subclauses 12.6.4.8 & 13.7.6).
- Support formatted, list-directed, and NAMELIST
transfers to internal parent units; support these, and unformatted
transfers, for external parent units.
- Support nested child defined derived type I/O.
- Parse DT'foo'(v-list) FORMAT data edit descriptors and passes
their strings &/or v-list values as arguments to the defined
formatted I/O routines.
- Fix problems with this feature encountered in semantics and
FORMAT valiation during development and end-to-end testing.
- Convert typeInfo::SpecialBinding from a struct to a class
after adding a member function.
Differential Revision: https://reviews.llvm.org/D104930
A recent change that extended semantic analysis for actual arguments
that associate with procedure dummy arguments exposed some bugs in
regression test suites due to points of confusion in symbol table
handling in situations where a generic interface contains a specific
procedure of the same name. When passing that name as an actual
argument, for example, it's necessary to take this possibility into
account because the symbol for the generic interface shadows the
symbol of the same name for the specific procedure, which is
what needs to be checked. So add a small utility that bypasses
the symbol for a generic interface in this case, and use it
where needed.
Differential Revision: https://reviews.llvm.org/D104929
Work around two problems with GCC 7.3.
One is its inability to implement "constexpr operator=(...) = default;"
in a class with a std::optional<> component; another is a legitimate-
looking warning about an unused variable.
Differential Revision: https://reviews.llvm.org/D104731
This patch adds the following nesting check for `barrier` constructs:
```
A barrier region may not be closely nested inside a worksharing, loop, task, taskloop, critical, ordered, atomic, or master region.
```
Also adds a test case for the check,
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D99888
This is *not* user-defined derived type I/O, but rather Fortran's
built-in capabilities for using derived type data in I/O lists
and NAMELIST groups.
This feature depends on having the derived type description tables
that are created by Semantics available, passed through compilation
as initialized static objects to which pointers can be targeted
in the descriptors of I/O list items and NAMELIST groups.
NAMELIST processing now handles component references on input
(e.g., "&GROUP x%component = 123 /").
The C++ perspectives of the derived type information records
were transformed into proper classes when it was necessary to add
member functions to them.
The code in Semantics that generates derived type information
was changed to emit derived type components in component order,
not alphabetic order.
Differential Revision: https://reviews.llvm.org/D104485
When a function is called in a specification expression, it must be
sufficiently defined, and cannot be a recursive call (10.1.11(5)).
The best fix for this is to change the contract for the procedure
characterization infrastructure to catch and report such errors,
and to guarantee that it does emit errors on failed characterizations.
Some call sites were adjusted to avoid cascades.
Differential Revision: https://reviews.llvm.org/D104330
When a program attempts to put something like a subprogram
into an array constructor, emit an error rather than crashing.
Differential Revision: https://reviews.llvm.org/D104336
Flang diverges from the llvm coding style in that it requires braces
around the bodies of if/while/etc statements, even when the body is
a single statement.
This commit adds the readability-braces-around-statements check to
flang's clang-tidy config file. Hopefully the premerge bots will pick it
up and report violations in Phabricator.
We also explicitly disable the check in the directories corresponding to
the Lower and Optimizer libraries, which rely heavily on mlir and llvm
and therefore follow their coding style. Likewise for the tools
directory.
We also fix any outstanding violations in the runtime and in
lib/Semantics.
Differential Revision: https://reviews.llvm.org/D104100
This patch adds the 4th Fortran specific semantic check for the OpenMP
allocate directive: "If a list item has the SAVE attribute, is a common
block name, or is declared in the scope of a module, then only predefined
memory allocator parameters can be used in the allocator clause".
Code in this patch was based on code from https://reviews.llvm.org/D93549/new/.
Differential Revision: https://reviews.llvm.org/D102400
It's possible to have several USE statements for the same module that
have different mixes of rename clauses and ONLY clauses. The presence
of a rename cause has the effect of hiding a previously associated name,
and the presence of an ONLY clause forces the name to be visible even in
the presence of a rename.
I fixed this by keeping track of the names that appear on rename and ONLY
clauses. Then, when processing the USE association of a name, I check to see
if it previously appeared in a rename clause and not in a USE clause. If so, I
remove its USE associated symbol. Also, when USE associating all of the names
in a module, I do not USE associate names that have appeared in rename clauses.
I also added a test.
Differential Revision: https://reviews.llvm.org/D104130
Fix Flang build after addition of a new OpenMP clauses for a Clang
patch (D99459). Flang is using TableGen to generation the declaration
of clause checks and the new clause was missing a definiton.
It's possible to specify refer to an undefined derived type as the type of a
component of another derived type and then never define the type of the
component. We were not detecting this situation. To fix this, I
changed the value of isForwardReferenced_ in the symbol's
DerivedTypeDetails and checked for it when performing other derived type
checks.
I also had to record the fact that error messages were previously
emitted for the same problem in some cases so that I could avoid
duplicate messages.
I also added a test.
Differential Revision: https://reviews.llvm.org/D103714
Implement the following semantic check:
"A list item may not appear in a linear clause, unless it is the loop iteration variable."
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D100224
To ensure that errors are emitted by CheckConformance and
its callers in all situations, it's necessary for the returned result
of that function to distinguish between three possible
outcomes: the arrays are known to conform at compilation time,
the arrays are known to not conform (and a message has been
produced), and an indeterminate result in which is not possible
to determine conformance. So convert CheckConformance's
result into an optional<bool>, and convert its confusing
Boolean flag arguments into a bit-set of named flags too.
Differential Revision: https://reviews.llvm.org/D103654
A recent change was made in https://reviews.llvm.org/D101482 to cope
with kind parameters. It had the side effect of generating some type
info symbols inside derived type scopes. Derived type scope symbols
are meant for components, and other/later compilation phases might
choke when finding compiler generated symbols there that are not
components.
This patch preserves the fix from D101482 while still generating the
symbols outside of derived type scopes.
Differential Revision: https://reviews.llvm.org/D103621
When a subroutine or function symbol is defined in an INTERFACE
block, it's okay if a symbol of the same name appears in a
scope between the global scope and the scope of the INTERFACE.
Differential Revision: https://reviews.llvm.org/D103580
Add some missing error messages, and permit the appearance
of EntityDetails symbols in dummy argument type characterization.
Differential Revision: https://reviews.llvm.org/D103576
When a procedure pointer with no interface is called by a
function reference, complain about the lack.
Differential Revision: https://reviews.llvm.org/D103573
In something like "ASSOCIATE(X=>T(1))", the "T(1)" is parsed
as a Variable because it looks like a function reference or
array reference; if it turns out to be a structure constructor,
which is something we can't know until we're able to attempt
generic interface resolution in semantics, the parse tree needs
to be fixed up by replacing the Variable with an Expr.
The compiler could already do this for putative function references
encapsulated as Exprs, so this patch moves some code around and
adds parser::Selector to the overloads of expression analysis.
Differential Revision: https://reviews.llvm.org/D103572
The constexpr-capable class evaluate::DynamicType represented
CHARACTER length only with a nullable pointer into the declared
parameters of types in the symbol table, which works fine for
anything with a declaration but turns out to not suffice to
describe the results of the ACHAR() and CHAR() intrinsic
functions. So extend DynamicType to also accommodate known
constant CHARACTER lengths, too; use them for ACHAR & CHAR;
clean up several use sites and fix regressions found in test.
Differential Revision: https://reviews.llvm.org/D103571
A procedure pointer is allowed to name a specific intrinsic function
from F'2018 table 16.2 as its interface, but not other intrinsic
procedures. Catch this error, and thereby also fix a crash resulting
from a failure later in compilation from failed characteristics;
while here, also catch the similar error with initializers.
Differential Revision: https://reviews.llvm.org/D103570
As a benign extension common to other Fortran compilers,
accept BOZ literals in array constructors w/o explicit
types, treating them as integers.
Differential Revision: https://reviews.llvm.org/D103569
In error recovery situations, the mappings from source locations
to scopes were failing in a way that tripped some asserts.
Specifically, FindPureProcedureContaining() wasn't coping well
when starting at the global scope. (And since the global scope
no longer has a source range, clean up the Semantics constructor
to avoid confusion.)
Differential Revision: https://reviews.llvm.org/D103567
It's possible to specify defined input/output procedures either as a
type-bound procedure of a derived type or as a defined-io-generic-spec. This
means that you can specify the same procedure in both mechanisms, which does
not cause problems. Alternatively, you can specify two different procedures to
be the defined input/output procedure for the same derived type. This is an
error. This change catches this error. The situation is slightly complicated
by parameterized derived types. Types with the same value for a KIND parameter
are treated as the same type while types with different KIND parameters are
treated as different types.
I implemented this check by adding a vector to keep track of which defined
input/output procedures had been seen for which derived types along with the
kind of procedure (read vs write and formatted vs unformatted). I also added
tests for non-parameterized types and types parameterized by KIND and LEN type
parameters.
I also removed an erroneous check from the code that creates runtime type
information.
Differential Revision: https://reviews.llvm.org/D103560
Each var argument to an attach or detach clause must be a
Fortran variable or array with the pointer or allocatable attribute.
This patch enforce this restruction.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D103279
This patch adds the following Fortran specific semantic checks for the OpenMP
Allocate directive.
1) A type parameter inquiry cannot appear in an ALLOCATE directive.
2) List items specified in the ALLOCATE directive must not have the ALLOCATABLE
attribute unless the directive is associated with an ALLOCATE statement.
Co-authored-by: Irina Dobrescu <irina.dobrescu@arm.com>
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D102061
Defined input/output procedures are specified in 12.6.4.8. There are different
versions for read versus write and formatted versus unformatted, but they all
share the same basic set of dummy arguments.
I added several checking functions to check-declarations.cpp along with a test.
In the process of implementing this, I noticed and fixed a typo in
.../lib/Evaluate/characteristics.cpp.
Differential Revision: https://reviews.llvm.org/D103045
A recent fix for problems with ENTRY statement handling didn't
get the case of a procedure dummy argument on an ENTRY statement
in an executable part right; the code presumed that those dummy
arguments would be objects, not entities that might be objects or
procedures. Fix.
Differential Revision: https://reviews.llvm.org/D103098
Dummy arguments of ENTRY statements in execution parts were
not being created as objects, nor were they being implicitly
typed.
When the symbol corresponding to an alternate ENTRY point
already exists (by that name) due to having been referenced
in an earlier call, name resolution used to delete the extant
symbol. This isn't the right thing to do -- the extant
symbol will be pointed to by parser::Name nodes in the parse
tree while no longer being part of any Scope.
Differential Review: https://reviews.llvm.org/D102948
This patch implements the following semantic check:
```
A master region may not be closely nested inside a work-sharing, loop, atomic, task, or taskloop region.
```
Adds a test case and also modifies a couple of existing test cases to include the check.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D100228
Add overloads to AsGenericExpr() in Evaluate/tools.h to take care
of wrapping an untyped DataRef or bare Symbol in a typed Designator
wrapped up in a generic Expr<SomeType>. Use the new overloads to
replace a few instances of code that was calling TypedWrapper<>()
with a dynamic type.
This new tool will be useful in lowering to drive some code that
works with typed expressions (viz., list-directed I/O list items)
when starting with only a bare Symbol (viz., NAMELIST).
Differential Revision: https://reviews.llvm.org/D102352
When producing the runtime type information for a component of a derived type
that had a LEN type parameter, we were not allowing a KIND parameter of the
derived type. This was causing one of the NAG correctness tests to fail
(.../hibiya/d5.f90).
I added a test to our own test suite to check for this.
Also, I fixed a typo in .../module/__fortran_type_info.f90.
I allowed KIND type parameters to be used for the declarations of components
that use LEN parameters by constant folding the value of the LEN parameter. To
make the constant folding work, I had to put the semantics::DerivedTypeSpec of
the associated derived type into the folding context. To get this
semantics::DerivedTypeSpec, I changed the value of the semantics::Scope object
that was passed to DescribeComponent() to be the derived type scope rather than
the containing non-derived type scope.
This scope change, in turn, caused differences in the symbol table output that
is checked in typeinfo01.f90. Most of these differences were in the order that
the symbols appeared in the dump. But one of them changed one of the values
from "CHARACTER(2_8,1)" to "CHARACTER(1_8,1)". I'm not sure if these changes
are significant. Please verify that the results of this test are still valid.
Also, I wonder if there are other situations in this code where we should be
folding constants. For example, what if the field of a component has a
component whose type is a PDT with a LEN type parameter, and the component's
declaration depends on the KIND type parameter of the current PDT. Here's an
example:
type string(stringkind)
integer,kind :: stringkind
character(stringkind) :: value
end type string
type outer(kindparam)
integer,kind :: kindparam
type(string(kindparam)) :: field
end type outer
I don't understand the code or what it's trying to accomplish well enough to
figure out if such cases are correctly handled by my new code.
Differential Revision: https://reviews.llvm.org/D101482
We were not correctly handling structure constructors that had forward
references to parameterized derived types. I harvested the code that checks
for forward references that was used during analysis of function call
expressions and called it from there and also called it during the
analysis of structure constructors.
I also added a test that will produce an internal error without this change.
Differential Revision: https://reviews.llvm.org/D101330
We were not checking that attributes that are supposed to be specific to
dummy arguments were not being used for local entities. I added the checks
along with tests for them.
After implementing these new checks, I found that one of the tests in
separate-mp02.f90 was erroneous, and I fixed it.
Differential Revision: https://reviews.llvm.org/D101126
Andrezj W. @ Arm discovered that the runtime derived type table
building code in semantics was detecting fatal errors in the tests
that the f18 driver wasn't printing. This patch fixes f18 so that
these messages are printed; however, the messages were not valid user
errors, and the rest of this patch fixes them up.
There were two sources of the bogus errors. One was that the runtime
derived type information table builder was calculating the shapes of
allocatable and pointer array components in derived types, and then
complaining that they weren't constant or LEN parameter values, which
of course they couldn't be since they have to have deferred shapes
and those bounds were expressions like LBOUND(component,dim=1).
The second was that f18 was forwarding the actual LEN type parameter
expressions of a type instantiation too far into the uses of those
parameters in various expressions in the declarations of components;
when an actual LEN type parameter is not a constant value, it needs
to remain a "bare" type parameter inquiry so that it will be lowered
to a descriptor inquiry and acquire a captured expression value.
Fixing this up properly involved: moving some code into new utility
function templates in Evaluate/tools.h, tweaking the rewriting of
conversions in expression folding to elide needless integer kind
conversions of type parameter inquiries, making type parameter
inquiry folding *not* replace bare LEN type parameters with
non-constant actual parameter values, and cleaning up some
altered test results.
Differential Revision: https://reviews.llvm.org/D101001
This patch adds semantic checks for the General Restrictions of the
Allocate Directive.
Since the requires directive is not yet implemented in Flang, the
restriction:
```
allocate directives that appear in a target region must
specify an allocator clause unless a requires directive with the
dynamic_allocators clause is present in the same compilation unit
```
will need to be updated at a later time.
A different patch will be made with the Fortran specific restrictions of
this directive.
I have used the code from https://reviews.llvm.org/D89395 for the
CheckObjectListStructure function.
Co-authored-by: Isaac Perry <isaac.perry@arm.com>
Reviewed By: clementval, kiranchandramohan
Differential Revision: https://reviews.llvm.org/D91159
We were erroneously not taking into account the constant values of LEN type
parameters of parameterized derived types when checking for argument
compatibility. The required checks are identical to those for assignment
compatibility. Since argument compatibility is checked in .../lib/Evaluate and
assignment compatibility is checked in .../lib/Semantics, I moved the common
code into .../lib/Evaluate/tools.cpp and changed the assignment compatibility
checking code to call it.
After implementing these new checks, tests in resolve53.f90 were failing
because the tests were erroneous. I fixed these tests and added new tests
to call03.f90 to test argument passing of parameterized derived types more
completely.
Differential Revision: https://reviews.llvm.org/D100989
We were erroneously emitting error messages for assignments of derived types
where the associated objects were instantiated with non-constant LEN type
parameters.
I fixed this by adding the member function MightBeAssignmentCompatibleWith() to
the class DerivedTypeSpec and calling it to determine whether it's possible
that objects of parameterized derived types can be assigned to each other. Its
implementation first compares the uninstantiated values of the types. If they
are equal, it then compares the values of the constant instantiated type
parameters.
I added tests to assign04.f90 to exercise this new code.
Differential Revision: https://reviews.llvm.org/D100868
An empty NAME= should mean that there is no C binding, not the
binding that would result from BIND(C) without a NAME=.
See 18.10.2p2.
Differential Revision: https://reviews.llvm.org/D100494