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
This patch adds lowering support for atomic read and write constructs.
Also added is pointer modelling code to allow FIR pointer like types to
be inferred and converted while lowering.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D122725
Co-authored-by: Kiran Chandramohan <kiran.chandramohan@arm.com>
This patch handles empty hint value for critical and atomic constructs.
This also adds checks and tests for hint clause on atomic constructs.
Reviewed By: peixin, kiranchandramohan, NimishMishra
Differential Revision: https://reviews.llvm.org/D123186
When known at compile time, Ew.d and Dw.d output edit descriptors
should respect limitations from the standard on the value of a
kP scale factor with respect to the digit count (d), at least for
values of k other than zero.
Set LBOUND() constant folding for parentheses expr. as ones
Array bounds should not propagate throught omitted bounds specifications or
temporary variables - fix constant folding in case of Parentheses<T> expression
by explicitly returning array of ones (or scalar in case of DIM=).
Add set of tests for (x) bounds checks (w/ and w/o 'parameter' arrays)
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D123838
Previously constant folding uses 'dim' without checks which leads to ICE if we
do not have DIM= parameter. And for inputs without DIM= we need to form an
array of rank size with computed bounds instead of single value.
Add additional PackageConstant function to simplify 'if (dim)' handling since we
need to distinguish between scalar initialization in case of DIM= argument and
rank=1 array.
Also add a few more tests with 'parameter' type to verify folding for constant
arrays.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D123237
A missing "!" in the call interface lowering caused all derived type
arguments without length parameters that require and explicit interface
to be passed via fir.box (runtime descriptor).
This was not the intent: there is no point passing a simple derived type
scalars or explicit shapes by descriptor just because they have an attribute
like TARGET. This would actually be problematic with existing code that is
not always 100% compliant: some code implicitly calls procedures with
TARGET dummy attributes (this is not something a compiler can enforce
if the call and procedure definition are not in the same file).
Add a Scope::IsDerivedTypeWithLengthParameter to avoid passing derived
types with only kind parameters by descriptor. There is no point, the
callee knows about the kind parameter values.
Differential Revision: https://reviews.llvm.org/D123990
When resolving a procedure reference, do not allow a successful
intrinsic procedure probe result to override an existing
symbol.
Differential Revision: https://reviews.llvm.org/D123905
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().
When an error occurs in a formatted sequential output statement
and no output was ever emitted, don't emit a blank record.
This matches the error case behavior of other Fortran compilers.
Differential Revision: https://reviews.llvm.org/D123734
The x%KIND inquiry needs to be supported when 'x' is itself
a complex part reference or a type parameter inquiry.
Differential Revision: https://reviews.llvm.org/D123733
A POINTER attribute statement is allowed to add the POINTER attribute
to a procedure entity that has already been declared, e.g. with an
INTERFACE block.
Differential Revision: https://reviews.llvm.org/D123732
f18 was emitting a warning about short character actual arguments to
subprograms and statement functions; every other compiler considers this
case to be an error.
Differential Revision: https://reviews.llvm.org/D123731
A predicate expression made ENDFILE statements significant
only for sequential files, but it's applicable to formatted
stream output as well.
Differential Revision: https://reviews.llvm.org/D123730
For parameterized derived type component initializers whose
expressions' types depend on parameter values, f18's current
scheme of analyzing the initialization expression once during
name resolution fails. For example,
type :: pdt(k)
integer, kind :: k
real :: component = real(0.0, kind=k)
end type
To handle such cases, it is necessary to re-analyze the parse
trees of these initialization expressions once for each distinct
initialization of the type.
This patch adds code to wipe an expression parse tree of its
typed expressions, and update those of its symbol table pointers
that reference type parameters, and then re-analyze that parse
tree to generate the properly typed component initializers.
Differential Revision: https://reviews.llvm.org/D123728
Prior to this patch, the semantics utility GetExpr() will crash
unconditionally if it encounters a typed expression in the parse
tree that has not been set by expression semantics. This is the
right behavior when called from lowering, by which time it is known
that the program had no fatal user errors, since it signifies a
fatal internal error. However, prior to lowering, in the statement
semantics checking code, a more nuanced test should be used before
crashing -- specifically, we should not crash in the face of a
missing typed expression when in error recovery mode.
Getting this right requires GetExpr() and its helper class to have
access to the semantics context, so that it can check AnyFatalErrors()
before crashing. So this patch touches nearly all of its call sites.
Differential Revision: https://reviews.llvm.org/D123873
When a procedure pointer or procedure dummy argument has a
defined interface, the rank of the pointer (or dummy) is the
rank of the interface.
Also tweak code discovered in shape analysis when investigating
this problam so that it returns a vector of emptied extents rather
than std::nullopt when the extents are not scope-invariant, so that
the rank can at least be known.
Differential Revision: https://reviews.llvm.org/D123727
When formatted input (not list-directed or NAMELIST) is in "BZ" mode,
either because a BZ control edit descriptor appeared in a FORMAT or
BLANK="ZERO" appeared in OPEN or READ, input editing must not skip
over blanks before or within the input field.
Differential Revision: https://reviews.llvm.org/D123725
To avoid clashing with names of user derived types, the redundant
syntax TYPE(intrinsic type spec) must be interpreted as a monomorphic
derived type when "intrinsic type spec" is a single word. This
affects TYPE(BYTE) and TYPE(DOUBLECOMPLEX), but not TYPE(DOUBLE COMPLEX)
in free form source.
Differential Revision: https://reviews.llvm.org/D123724
Items in NAMELIST groups might be host-associated implicitly-typed
variables, but name resolution can't know that when the NAMELIST
appears in a specification part and the host's execution part has
not yet been analyzed. So defer NAMELIST group item name resolution
to the end of the execution part. This is safe because nothing
else in name resolution depends on whether a variable is in a
NAMELIST group or not.
Differential Revision: https://reviews.llvm.org/D123723
Construct entities from ASSOCIATE, SELECT TYPE, and SELECT RANK
are modifiable if the are associated with modifiable variables
without vector subscripts. Update WhyNotModifiable() to accept
construct entities that are appropriate.
A need for more general error reporting from one overload of
WhyNotModifiable() caused its result type to change to
std::optional<parser::Message> instead of ::MessageFixedText,
and this change had some consequences that rippled through
call sites.
Some test results that didn't allow for modifiable construct
entities needed to be updated.
Differential Revision: https://reviews.llvm.org/D123722
TYPE IS and CLASS IS guards in SELECT TYPE constructs are
allowed to specify the same type as the type of the selector
but f18's implementation of that predicate required strict
equality of the derived type representations. We need to
allow for assumed values of LEN type parameters to match
explicit and deferred type parameter values in the selector
and require equality for KIND type parameters. Implement
DerivedTypeSpec::Match() to perform this more relaxed type
comparison, and use it in check-select-type.cpp.
Differential Revision: https://reviews.llvm.org/D123721
It is possible for generic interfaces of equivalent (but not necessarily
identical -- operator(.eq.) is equivalent to operator(==)) names to
be declared in a host scope and a nested scope, and the nested declaration
should function as an extension of the host's.
Differential Revision: https://reviews.llvm.org/D123719
A generic interface (however spelled) can have the same name as
an intrinsic procedure in the same scope. When an explicit INTRINSIC
attribute statement appears in a nested scope, semantics was
unconditionally declaring a new symbol that hid the generic entirely.
Catch this case and create instead a host association symbol for
the generic that can then be decorated with the INTRINSIC attribute.
Differential Revision: https://reviews.llvm.org/D123718
When formatted non-advancing output ends in a control edit descriptor
like nX or Tn or TRn that effectively extends the record, fill any
gap with explicit blanks at the completion of the WRITE.
Differential Revision: https://reviews.llvm.org/D123716
Formatted READs of REAL should convert the exception flags from
the decimal-to-binary conversion library into real runtime FP
exceptions so that they at least show up in the termination message
of a STOP statement.
Differential Revision: https://reviews.llvm.org/D123714
Fortran allows a generic interface to have he same name as an
intrinsic procedure. If the intrinsic is explicitly marked with
the INTRINSIC attribute, restrictions apply (C848) - the generic
must contain only functions or subroutines, depending on the
intrinsic. Explicit or not, the generic overrides the intrinsic,
but the intrinsic behavior must still be available for calls
whose actual arguments do not match any of the specific procedures.
Semantics was not checking constraint C848, and it didn't allow
an explicit INTRINSIC attribute on a name of a generic interface.
Differential Revision: https://reviews.llvm.org/D123713
Shape analysis of RESHAPE(..., SHAPE=s) should of course return
the SHAPE= actual argument when it is constant; but when it is
not, its length is still known, and thus so is the rank of the
result of RESHAPE(), and shape analysis should at least return
a shape vector of the right length rather than a result that
makes the result appear to be a scalar, which can lead to some
bogus error messages.
Also, while here: rename a private GetShapeHelper::AsShape()
routine so that it can't be confused with the ones in the API
of shape.h.
Differential Revision: https://reviews.llvm.org/D123712
A recent change to implement UTF-8 encoding should have
made the encoding conditional only for CHARACTER(KIND=1)
to enable UTF-8 output vs. Latin-1 or whatever. UTF-8 output
of wider CHARACTER kinds should not be conditional (until we choose
to support UCS-16, maybe). So wider CHARACTER kinds are being
emitted with extra zero bytes; this patch fixes them.
Differential Revision: https://reviews.llvm.org/D123711
When a type specification appears in the prefix of a FUNCTION statement,
defer its processing as late as possible so that any symbols in the
tpe specification can be resolved in the function's scope to local
declarations, including use-associated symbols. f18 was already doing
this deferral in a limited form for derived types, and this patch
makes it work for intrinsic type parameter values as well.
In short, "real(kind(x)) function foo(x)" now works as it should.
"As late as possible" means the end of the specification part, or
the first appearance of the function result name in the specification
part.
Differential Revision: https://reviews.llvm.org/D123705
Fortran admits a few ways to have multiple symbols with the
same name in the same scope. Two of them involve generic
interfaces (from INTERFACE or GENERIC, the syntax doesn't matter);
these are allowed to inhabit a scope with either a derived type or
a subprogram that is also a specific procedure of the generic.
(But not both a derived type and a subprogram; they could not
cohabit a scope anyway, generic or not.)
In cases of USE association, f18 needs to be capable of combining
use-associated generic interfaces with other use-associated entities.
Two generics get merged (this case was nearly correct); a generic
and a derived type can merge into a GenericDetails with a shadowed
derivedType(); and a generic can replace or ignore a use-associated
procedure of the same name so long as that procedure is already
one of its specifics.
Further, these modifications to the use-associated generic
interface must be made to a local copy of the symbol. The previous
code was messing directly with the symbol in the module's scope.
The fix is basically a reimplementation of the member function
DoAddUse() in name resolution.
Differential Revision: https://reviews.llvm.org/D123704
Error messages can have a list of attachments; these are used to point
to related source locations, supply additional information, and to
encapsulate error messages that were *not* emitted in a given context
to explain why a warning was justified.
This patch adds a message severity ("Because") for that last case,
and extends to AttachTo() API to provide a means for overriding
the severity of an attached message.
Some existing message attachments had their severities adjusted,
now that we're printing them. And operator==() for Message was
cleaned up while debugging after I noticed that it was recursively
O(N**2) and subject to returning a false positive.
Differential Revision: https://reviews.llvm.org/D123710
The intrinsics DREAL, DIMAG, and DCONJG are from Fortran 77 extensions.
For DREAL, the type of argument is extended to any complex. For DIMAG
and DCONJG, the type of argument for them should be complex(8). For DIMAG,
the result type should be real(8). For DCONJG, the result type should be
complex(8). Fix the intrinsic interface for them and add test cases for
the semantic checks and the lowering.
Reviewed By: Jean Perier
Differential Revision: https://reviews.llvm.org/D123459
The float number is represented as (-1)^s * 1.f * 2^(-127) for 32-bit,
where s is the signed flag, f is the mantissa. When the exponent bits
are all zeros, the float number is represented as (-1)^s * 0.f *2^(-126)
for 32-bit, in which case, the intPart is '0'.
Reviewed By: Jean Perier
https://reviews.llvm.org/D123673
During real range reduction to [0.5, 4) with
SQRT(2**(2a) * x) = SQRT(2**(2a)) * SQRT(x) = 2**a * SQRT(x)
we fall into inf. recursion if IsZero() == true.
Explicitly handle SQRT(0.0) instead of additional checks during folding. Also
add helpers for +0.0/-0.0 generation to clean up a bit.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D123131
The semantics of `-mmlir` are identical to `-mllvm`. The only notable
difference is that `-mmlir` options should be forwarded to MLIR rather
than LLVM.
Note that MLIR llvm::cl options are lazily constructed on demand (see
the definition of options in PassManagerOptions.cpp). This means that:
* MLIR global options are only visible when explicitly initialised and
displayed only when using `-mmlir --help`,
* Flang and LLVM global options are always visible and displayed when
using either `-mllvm -help` or `-mmlir --help`.
In other words, `-mmlir --help` is a superset of `-mllvm --help`. This is not
ideal, but we'd need to refactor all option definitions in Flang and
LLVM to improve this. I suggesting leaving this for later.
Differential Revision: https://reviews.llvm.org/D123297
https://reviews.llvm.org/D123211 broke builds that set both
`LLVM_BUILD_LLVM_DYLIB` and `LLVM_LINK_LLVM_DYLIB` (see [1]). This patch
fixes that.
The build failure was caused by the fact that the LLVMPasses library,
which is an LLVM "component", was listed directly as link-time
dependency. Instead, one should use `LINK_COMPONENTS` in CMake files. I
made an identical mistake recently and then subsequently fixed it in
https://reviews.llvm.org/D121461 - please visit that revision for more
detail.
I'm merging this without a review. The change is straightforward, we
recently discussed it and I was able to confirm locally that it fixes
the build issue.
[1] https://lab.llvm.org/buildbot/#/builders/177/builds/4619
Correct the implementation of non-advancing I/O after some testing
to ensure that T tab edit descriptors are not allowed to back up
into positions of a record prior to where it stood at the beginning
of the I/O statement.
Differential Revision: https://reviews.llvm.org/D123709
Catch and nicely describe errors in CASE range values
that are out of range for the type of the SELECT CASE.
Differential Revision: https://reviews.llvm.org/D123708
Add a test with a range of num_images() intrinsic function
invocations, including the standard-conforming but previously
untested 'team' argument. Also test that several non-conforming
num_images() invocations generate the correct error messages.
Differential Revision: https://reviews.llvm.org/D121938
When padding is required in a COMMON block to ensure alignment
of a component, emit a portability warning.
Differential Revision: https://reviews.llvm.org/D123706
This patch supports lowering parse-tree to MLIR of ordered threads
directive following Section 2.19.9 of the OpenMP 5.1 standard.
This is part of the upstreaming effort from the fir-dev branch in [1].
[1] https://github.com/flang-compiler/f18-llvm-project
Reviewed By: shraiysh
Differential Revision: https://reviews.llvm.org/D123590
This patch supports the following checks for ORDERED construct:
```
[5.1] 2.19.9 ORDERED Construct
The worksharing-loop or worksharing-loop SIMD region to which an ordered
region corresponding to an ordered construct without a depend clause
binds must have an ordered clause without the parameter specified on the
corresponding worksharing-loop or worksharing-loop SIMD directive.
The worksharing-loop region to which an ordered region that corresponds
to an ordered construct with any depend clauses binds must have an
ordered clause with the parameter specified on the corresponding
worksharing-loop directive.
An ordered construct with the depend clause specified must be closely
nested inside a worksharing-loop (or parallel worksharing-loop)
construct.
An ordered region that corresponds to an ordered construct with the simd
clause specified must be closely nested inside a simd or
worksharing-loop SIMD region.
```
Reviewed By: kiranchandramohan, shraiysh, NimishMishra
Differential Revision: https://reviews.llvm.org/D113399