The combined initializers constructed from DATA statements and explicit
static initialization in declarations needs to include derived type
component default initializations, overriding those default values
without complaint with values from explicit DATA statement or declaration
initializations when they overlap. This also has to work for objects
with storage association due to EQUIVALENCE. When storage association causes
default component initializations to overlap, emit errors if and only
if the values differ (See Fortran 2018 subclause 19.5.3, esp. paragraph
10).
The f18 front-end has a module that analyzes and converts DATA statements
into equivalent static initializers for objects. For storage-associated
objects, compiler-generated objects are created that overlay the entire
association and fill it with a combined initializer. This "data-to-inits"
module already exists, and this patch is essentially extension and
clean-up of its machinery to complete the job.
Also: emit EQUIVALENCE to module files; mark compiler-created symbols
and *don't* emit those to module files; check non-static EQUIVALENCE
sets for conflicting default component initializations, so lowering
doesn't have to check them or emit diagnostics.
Differential Revision: https://reviews.llvm.org/D109022
The double precision KindCode was ignored when building the interface
of specific intrinsic procedures leading to bad semantics checks.
Differential Revision: https://reviews.llvm.org/D108828
ApplyElementwise on character operation was always creating a result
ArrayConstructor with the length of the left operand. This is not
correct for concatenation and SetLength operations.
Compute and thread the length to the spot creating the ArrayConstructor
so that the length is correct for those character operations.
Differential Revision: https://reviews.llvm.org/D108711
When the upper bound is less than the lower bound, the extent is zero. This is
specified in section 8.5.8.2, paragraph 3.
Note that similar problems exist in the lowering code. This change only fixes
the problem for the front end.
I also added a test.
Differential Revision: https://reviews.llvm.org/D107832
Like the similar legacy extension FLOAT(), DFLOAT() represents a
conversion from default integer to DOUBLE PRECISION. Rewrite
into a conversion operation.
Differential Revision: https://reviews.llvm.org/D107489
Dummy procedures can be defined as subprograms with explicit
interfaces, e.g.
subroutine subr(dummy)
interface
subroutine dummy(x)
real :: x
end subroutine
end interface
! ...
end subroutine
but the symbol table had no means of marking such symbols as dummy
arguments, so predicates like IsDummy(dummy) would fail. Add an
isDummy_ flag to SubprogramNameDetails, analogous to the corresponding
flag in EntityDetails, and set/test it as needed.
Differential Revision: https://reviews.llvm.org/D106697
The result expression for the analysis of a Component is not (longer)
valid in the expression traversal framework used by IsSimplyContiguousHelper
now that it has a tri-state result. Fix so that any result of
analyzing the component symbol is required to be true, not just
present.
Differential Revision: https://reviews.llvm.org/D106693
According to C7109, "A boz-literal-constant shall appear only as a
data-stmt-constant in a DATA statement, or where explicitly allowed in
16.9 as an actual argument of an intrinsic procedure." This change
enforces that constraint for output list items.
I also added a general interface to determine if an expression is a BOZ
literal constant and changed all of the places I could find where it
could be used.
I also added a test.
This change stemmed from the following issue --
https://gitlab-master.nvidia.com/fortran/f18-stage/issues/108
Differential Revision: https://reviews.llvm.org/D106893
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
There are situations where the arguments of intrinsics must be
conformable, which is defined in section 3.36. This means they must
have "the same shape, or one being an array and the other being scalar".
But the check we were actually making was that their ranks were the same.
This change fixes that and adds a test for the UNPACK intrinsic, where
the FIELD argument "shall be conformable with MASK".
Differential Revision: https://reviews.llvm.org/D104936
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
Refactor the recently-implemented MAXVAL/MINVAL folding so
that the parts that can be used to implement other reduction
transformational intrinsic function folding are exposed.
Use them to implement folding of IALL, IANY, IPARITY,
SUM. and PRODUCT. Replace the folding of ALL & ANY to
use the new infrastructure and become able to handle DIM=
arguments.
Differential Revision: https://reviews.llvm.org/D104562
Do not use ultimate symbols in DescriptorInquiry. Using the ultimate
symbol may lead to issues later for at least two reasons:
- The original symbols may have volatile/asynchronous attributes that
the ultimate may not have. Later phases working on the DescriptorInquiry
would then not apply potential care required by these attributes.
- HostAssociatedDetails symbols are used by OpenMP for symbols with
special OpenMP attributes inside OpenMP region (e.g variables with
private attribute), so it is very important to preserve this
aspect in the DescriptorInquiry, that would otherwise apply on the
symbol outside of the region.
Differential Revision: https://reviews.llvm.org/D104385
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
Recent code for folding MINVAL() didn't allow for architectures
whose C/C++ char type is unsigned, so the value of the maximum
Fortran character was incorrect. This was caught by the
folding20.f90 test. The fix is to avoid numeric_limits<> and
use hard values for max signed integers of various character kinds.
Pushing into llvm-project/main to restore ARM/POWER buildbots.
Implement constant folding for the reduction transformational
intrinsic functions MAXVAL and MINVAL.
In anticipation of more folding work to follow, with (I hope)
some common infrastructure, these two have been implemented in a
new header file.
Differential Revision: https://reviews.llvm.org/D104337
I added the only check that wasn't already tested along with tests for
many valid and invalid arguments.
Differential Revision: https://reviews.llvm.org/D104318
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
Add some missing error messages, and permit the appearance
of EntityDetails symbols in dummy argument type characterization.
Differential Revision: https://reviews.llvm.org/D103576
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
The code for folding calls to the intrinsic function CMPLX was
incorrectly dependent on the number of arguments to distinguish its
two cases (conversion from one kind of complex to another, and
composition of a complex value from real & imaginary parts).
This was wrong since the optional KIND= argument has already been
taken into account by intrinsic processing; instead, the type of
the first argument should decide the issue.
Differential Revision: https://reviews.llvm.org/D103568
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
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
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
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
F18 supports the standard intrinsic function SELECTED_REAL_KIND
but not its synonym in the standard module IEEE_ARITHMETIC
named IEEE_SELECTED_REAL_KIND until this patch.
Differential Revision: https://reviews.llvm.org/D100066
We were not folding type parameter inquiries for the form 'var%typeParam'
where 'typeParam' was a KIND or LEN type parameter of a derived type and 'var'
was a designator of the derived type. I fixed this by adding code to the
function 'FoldOperation()' for 'TypeParamInquiry's to handle this case. I also
cleaned up the code for the case where there is no designator.
In order to make the error messages correctly refer to both the points of
declaration and instantiation, I needed to add an argument to the function
'InstantiateIntrinsicType()' for the location of the instantiation.
I also changed the formatting of 'TypeParamInquiry' to correctly format this
case. I also added tests for both KIND and LEN type parameter inquiries in
resolve104.f90.
Making these changes revealed an error in resolve89.f90 and caused one of the
error messages in assign04.f90 to be different.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D99892
We were not folding type parameter inquiries for the form 'var%typeParam'
where 'typeParam' was a KIND or LEN type parameter of a derived type and 'var'
was a designator of the derived type. I fixed this by adding code to the
function 'FoldOperation()' for 'TypeParamInquiry's to handle this case. I also
cleaned up the code for the case where there is no designator.
In order to make the error messages correctly refer to both the points of
declaration and instantiation, I needed to add an argument to the function
'InstantiateIntrinsicType()' for the location of the instantiation.
I also changed the formatting of 'TypeParamInquiry' to correctly format this
case. I also added tests for both KIND and LEN type parameter inquiries in
resolve104.f90.
Making these changes revealed an error in resolve89.f90 and caused one of the
error messages in assign04.f90 to be different.
Differential Revision: https://reviews.llvm.org/D99892
f18 was emitting a bogus error message about the lack of a TARGET
attribute when a pointer was initialized with a component of a
variable that was a legitimate TARGET.
Differential Revision: https://reviews.llvm.org/D99665
Folding of LOGICAL intrinsic procedure was missing in the front-end causing
crash when using it in parameter expressions.
Simply fold LOGICAL calls to evaluate::Convert<T>.
Differential Revision: https://reviews.llvm.org/D99346
Replace semantics::SymbolSet with alternatives that clarify
whether the set should order its contents by source position
or not. This matters because positionally-ordered sets must
not be used for Symbols that might be subjected to name
replacement during name resolution, and address-ordered
sets must not be used (without sorting) in circumstances
where the order of their contents affects the output of the
compiler.
All set<> and map<> instances in the compiler that are keyed
by Symbols now have explicit Compare types in their template
instantiations. Symbol::operator< is no more.
Differential Revision: https://reviews.llvm.org/D98878
In parser::AllCookedSources, implement a map from CharBlocks to
the CookedSource instances that they cover. This permits a fast
Find() operation based on std::map::equal_range to map a CharBlock
to its enclosing CookedSource instance.
Add a creation order number to each CookedSource. This allows
AllCookedSources to provide a Precedes(x,y) predicate that is a
true source stream ordering between two CharBlocks -- x is less
than y if it is in an earlier CookedSource, or in the same
CookedSource at an earlier position.
Add a reference to the singleton SemanticsContext to each Scope.
All of this allows operator< to be implemented on Symbols by
means of a true source ordering. From a Symbol, we get to
its Scope, then to the SemanticsContext, and then use its
AllCookedSources reference to call Precedes().
Differential Revision: https://reviews.llvm.org/D98743
Fortran permits a reference to a function whose result is a pointer
to be used as a definable variable in any context where a
designator could appear. This patch wrings out remaining bugs
with such usage and adds more testing.
The utility predicate IsProcedurePointer(expr) had a misleading
name which has been corrected to IsProcedurePointerTarget(expr).
Differential Revision: https://reviews.llvm.org/D98555
It's possible to define a procedure whose interface depends on a procedure
which has an interface that depends on the original procedure. Such a circular
definition was causing the compiler to fall into an infinite loop when
resolving the name of the second procedure. It's also possible to create
circular dependency chains of more than two procedures.
I fixed this by adding the function HasCycle() to the class DeclarationVisitor
and calling it from DeclareProcEntity() to detect procedures with such
circularly defined interfaces. I marked the associated symbols of such
procedures by calling SetError() on them. When processing subsequent
procedures, I called HasError() before attempting to analyze their interfaces.
Unfortunately, this did not work.
With help from Tim, we determined that the SymbolSet used to track the
erroneous symbols was instantiated using a "<" operator which was defined using
the location of the name of the procedure. But the location of the procedure
name was being changed by a call to ReplaceName() between the times that the
calls to SetError() and HasError() were made. This caused HasError() to
incorrectly report that a symbol was not in the set of erroneous symbols.
I fixed this by changing SymbolSet to be an unordered set that uses the
contents of the name of the symbol as the basis for its hash function. This
works because the contents of the name of the symbol is preserved by
ReplaceName() even though its location changes.
I also fixed the error message used when reporting recursively defined
dummy procedure arguments by removing extra apostrophes and sorting the
list of symbols.
I also added tests that will crash the compiler without this change.
Note that the "<" operator is used in other contexts, for example, in the map
of characterized procedures, maps of items in equivalence sets, maps of
structure constructor values, ... All of these situations happen after name
resolution has been completed and all calls to ReplaceName() have already
happened and thus are not subject to the problem I ran into when ReplaceName()
was called when processing procedure entities.
Note also that the implementation of the "<" operator uses the relative
location in the cooked character stream as the basis of its implementation.
This is potentially problematic when symbols from diffent compilation units
(for example symbols originating in .mod files) are put into the same map since
their names will appear in two different source streams which may not be
allocated in the same relative positions in memory. But I was unable to create
a test that caused a problem. Using a direct comparison of the content of the
name of the symbol in the "<" operator has problems. Symbols in enclosing or
parallel scopes can have the same name. Also using the location of the symbol
in the cooked character stream has the advantage that it preserves the the
order of the symbols in a structure constructor constant, which makes matching
the values with the symbols relatively easy.
This patch supersedes D97749.
Differential Revision: https://reviews.llvm.org/D97774
It's possible to define a procedure whose interface depends on a procedure
which has an interface that depends on the original procedure. Such a circular
definition was causing the compiler to fall into an infinite loop when
resolving the name of the second procedure. It's also possible to create
circular dependency chains of more than two procedures.
I fixed this by adding the function HasCycle() to the class DeclarationVisitor
and calling it from DeclareProcEntity() to detect procedures with such
circularly defined interfaces. I marked the associated symbols of such
procedures by calling SetError() on them. When processing subsequent
procedures, I called HasError() before attempting to analyze their interfaces.
Unfortunately, this did not work.
With help from Tim, we determined that the SymbolSet used to track the
erroneous symbols was instantiated using a "<" operator which was defined using
the location of the name of the procedure. But the location of the procedure
name was being changed by a call to ReplaceName() between the times that the
calls to SetError() and HasError() were made. This caused HasError() to
incorrectly report that a symbol was not in the set of erroneous symbols.
I fixed this by changing SymbolSet to be an unordered set that uses the
contents of the name of the symbol as the basis for its hash function. This
works because the contents of the name of the symbol is preserved by
ReplaceName() even though its location changes.
I also fixed the error message used when reporting recursively defined dummy
procedure arguments.
I also added tests that will crash the compiler without this change.
Note that the "<" operator is used in other contexts, for example, in the map
of characterized procedures, maps of items in equivalence sets, maps of
structure constructor values, ... All of these situations happen after name
resolution has been completed and all calls to ReplaceName() have already
happened and thus are not subject to the problem I ran into when ReplaceName()
was called when processing procedure entities.
Note also that the implementation of the "<" operator uses the relative
location in the cooked character stream as the basis of its implementation.
This is potentially problematic when symbols from diffent compilation units
(for example symbols originating in .mod files) are put into the same map since
their names will appear in two different source streams which may not be
allocated in the same relative positions in memory. But I was unable to create
a test that caused a problem. Using a direct comparison of the content of the
name of the symbol in the "<" operator has problems. Symbols in enclosing or
parallel scopes can have the same name. Also using the location of the symbol
in the cooked character stream has the advantage that it preserves the the
order of the symbols in a structure constructor constant, which makes matching
the values with the symbols relatively easy.
This change supersedes D97201.
Differential Revision: https://reviews.llvm.org/D97749
This reverts commit 07de0846a5.
The original patch has caused 6 out 8 of Flang's public buildbots to
fail. As I'm not sure what the fix should be, I'm reverting this for
now. Please see https://reviews.llvm.org/D97201 for more context and
discussion.
It's possible to define a procedure whose interface depends on a procedure
which has an interface that depends on the original procedure. Such a circular
definition was causing the compiler to fall into an infinite loop when
resolving the name of the second procedure. It's also possible to create
circular dependency chains of more than two procedures.
I fixed this by adding the function HasCycle() to the class DeclarationVisitor
and calling it from DeclareProcEntity() to detect procedures with such
circularly defined interfaces. I marked the associated symbols of such
procedures by calling SetError() on them. When processing subsequent
procedures, I called HasError() before attempting to analyze their interfaces.
Unfortunately, this did not work.
With help from Tim, we determined that the SymbolSet used to track the
erroneous symbols was instantiated using a "<" operator which was
defined using the name of the procedure. But the procedure name was
being changed by a call to ReplaceName() between the times that the
calls to SetError() and HasError() were made. This caused HasError() to
incorrectly report that a symbol was not in the set of erroneous
symbols. I fixed this by making SymbolSet be an ordered set, which does
not use the "<" operator.
I also added tests that will crash the compiler without this change.
And I fixed the formatting on an error message from a previous update.
Differential Revision: https://reviews.llvm.org/D97201
Fortran 2018 explicitly permits an ignored type declaration
for the result of a generic intrinsic function. See the comment
added to Semantics/expression.cpp for an explanation of why this
is somewhat dangerous and worthy of a warning.
Differential Revision: https://reviews.llvm.org/D96879
It's possible to define a procedure that has a procedure dummy argument which
names the procedure that contains it. This was causing the compiler to fall
into an infinite loop when characterizing a call to the procedure.
Following a suggestion from Peter, I fixed this be maintaining a set of
procedure symbols that had already been seen while characterizing a procedure.
This required passing a new parameter to the functions that characterized a
Procedure, a DummyArgument, and a DummyProcedure.
I also added several tests that will crash the compiler without this change.
Differential Revision: https://reviews.llvm.org/D96631
Constant folding for calls to LBOUND() was not working when the lower bound of
a constant array was not 1.
I fixed this and re-enabled the test in Evaluate/folding16.f90 that previously
was silently failing. I slightly changed the test to parenthesize the first
argument to exercise all of the new code.
Differential Revision: https://reviews.llvm.org/D95894
Split up MeasureSizeInBytes() so that array element sizes can be
calculated accurately; use the new API in some places where
DynamicType::MeasureSizeInBytes() was being used but the new
API performs better due to TypeAndShape having precise CHARACTER
length information.
Differential Revision: https://reviews.llvm.org/D95897
Implement IEEE_SUPPORT_DATATYPE() and other inquiry intrinisic
functions from the intrinsic module IEEE_ARITHMETIC, folding all of
their results to .TRUE.
Differential Revision: https://reviews.llvm.org/D95830
Analyze the shape of the result of TRANSFER(ptr,array) correctly
when "ptr" is an array of deferred shape. Fixing this bug led to
some refactoring and concentration of common code in TypeAndShape
member functions with code in general shape and character length
analysis, and this led to some regression test failures that have
all been cleaned up.
Differential Revision: https://reviews.llvm.org/D95744
Legacy Fortran implementations support an alternative form of the
PARAMETER statement; it differs syntactically from the standard's
PARAMETER statement by lacking parentheses, and semantically by
using the type and shape of the initialization expression to define
the attributes of the named constant. (GNU Fortran gets that part
wrong; Intel Fortran and nvfortran have full support.)
This patch disables the old style PARAMETER statement by default, as
it is syntactically ambiguous with conforming assignment statements;
adds a new "-falternative-parameter-statement" option to enable it;
and implements it correctly when enabled.
Fixes https://bugs.llvm.org/show_bug.cgi?id=48774, in which a user
tripped over the syntactic ambiguity.
Differential Revision: https://reviews.llvm.org/D95697
There were two problems with constant arrays whose lower bound is not 1.
First, when folding the arrays, we were creating the folded array to have lower
bounds of 1 but, we were not re-adjusting their lower bounds to the
declared values. Second, we were not calculating the extents correctly.
Both of these problems led to bogus error messages.
I fixed the first problem by adjusting the lower bounds in
NonPointerInitializationExpr() in Evaluate/check-expression.cpp. I wrote the
class ArrayConstantBoundChanger, which is similar to the existing class
ScalarConstantExpander. In the process of implementing and testing it, I found
a bug that I fixed in ScalarConstantExpander which caused it to infinitely
recurse on parenthesized expressions. I also removed the unrelated class
ScalarExpansionVisitor, which was not used.
I fixed the second problem by changing the formula that calculates upper bounds
in in the function ComputeUpperBound() in Evaluate/shape.cpp.
I added tests that trigger the bogus error messages mentioned above along with
a constant folding tests that uses array operands with shapes that conform but
have different bounds.
In the process of adding tests, I discovered that tests in
Evaluate/folding09.f90 and folding16.f90 were written incorrectly, and I
fixed them. This also revealed a bug in contant folding of the
intrinsic "lbounds" which I plan to fix in a later change.
Differential Revision: https://reviews.llvm.org/D95449
Correct the analysis of references to transformational intrinsic
functions that have different semantics based on the presence or
absence of a DIM= argument; add shape analysis for UNPACK().
Differential Revision: https://reviews.llvm.org/D94716
Expressions emitted to module files and error messages
sometimes contain conversions of integer results of inquiry
intrinsics; these are usually not needed, and can conflict
with "int" in the user's namespace. Improve folding so that
these conversions don't appear, and do some other clean-up
in adjacent code.
Differential Revision: https://reviews.llvm.org/D95172
* IsArrayElement() needs another option to control whether it
should ignore trailing component references.
* Add IsObjectPointer().
* Add const Scope& variants of IsFunction() and IsProcedure().
* Make TypeAndShape::Characterize() work with procedure bindings.
* Handle CHARACTER length in MeasureSizeInBytes().
* Fine-tune FindExternallyVisibleObject()'s handling of dummy arguments
to conform with Fortran 2018: only INTENT(IN) and dummy pointers
in pure functions signify; update two tests accordingly.
Also: resolve some stylistic inconsistencies and add a missing
"const" in the expression traversal template framework.
Differential Revision: https://reviews.llvm.org/D95011
The utility routine WhyNotModifiable() needed to become more
aware of the use of pointers in data-refs; the targets of
pointer components are sometimes modifiable even when the
leftmost ("base") symbol of a data-ref is not.
Added a new unit test for WhyNotModifiable() that uses internal
READ statements (mostly), since I/O semantic checking uses
WhyNotModifiable() for all its definability checking.
Differential Revision: https://reviews.llvm.org/D94849
When a reference to a generic interface occurs in a specification
expression that must be emitted to a module file, we have a problem
when the generic resolves to a function whose name is inaccessible
due to being PRIVATE or due to a conflict with another use of the
same name in the scope. In these cases, construct a new name for
the specific procedure and emit a renaming USE to the module file.
Also, relax enforcement of PRIVATE when analyzing module files.
Differential Revision: https://reviews.llvm.org/D94815
In some contexts, including the motivating case of determining whether
the expressions that define the shape of a variable are "constant expressions"
in the sense of the Fortran standard, expression rewriting via Fold()
is not necessary, and should not be required. The inquiry intrinsics LBOUND,
UBOUND, and SIZE work correctly now in specification expressions and are
classified correctly as being constant expressions (or not). Getting this right
led to a fair amount of API clean-up as a consequence, including the
folding of shapes and TypeAndShape objects, and new APIs for shapes
that do not fold for those cases where folding isn't needed. Further,
the symbol-testing predicate APIs in Evaluate/tools.h now all resolve any
associations of their symbols and work transparently on use-, host-, and
construct-association symbols; the tools used to resolve those associations have
been defined and documented more precisely, and their clients adjusted as needed.
Differential Revision: https://reviews.llvm.org/D94561
Internal subprograms have explicit interfaces. If an internal subprogram has
an alternate return, we check its explicit interface. But we were not
putting the label values of alternate returns into the actual argument.
I fixed this by changing the definition of actual arguments to be able
to contain a common::Label and putting the label for an alternate return
into the actual argument.
I also verified that we were already doing all of the semantic checking
required for alternate returns and removed a "TODO" for this.
I also added the test altreturn06.f90.
Differential Revision: https://reviews.llvm.org/D94017
Elemental intrinsic function folding was not taking the lower
bounds of constant array arguments into account; these lower bounds
can be distinct from 1 when named constants appear as arguments.
LLVM bugzilla #48437.
Differential Revision: https://reviews.llvm.org/D93321
STORAGE_SIZE() is a standard inquiry intrinsic (size in bits
of an array element of the same type as the argument); SIZEOF()
is a common extension that returns the size in bytes of its
argument; C_SIZEOF() is a renaming of SIZEOF() in module ISO_C_BINDING.
STORAGE_SIZE() and SIZEOF() are implemented via rewrites to
expressions; these expressions will be constant when the necessary
type parameters and bounds are also constant.
Code to calculate the sizes of types (with and without alignment)
was isolated into Evaluate/type.* and /characteristics.*.
Code in Semantics/compute-offsets.* to calculate sizes and alignments
of derived types' scopes was exposed so that it can be called at type
instantiation time (earlier than before) so that these inquiry intrinsics
could be called from specification expressions.
Differential Revision: https://reviews.llvm.org/D93322
Remove resolved & moot TODO comments in Common/, Parser/,
and Evaluate/. Address a pending one relating to parsing
ambiguity in DATA statement constants, handling it with
symbol table information in Semantics and adding a test.
Differential Revision: https://reviews.llvm.org/D93323
The semantic analysis of index-names of FORALL statements looks up symbols with
the same name as the index-name. This is needed to exclude symbols that are
not objects. But if the symbol found is host-, use-, or construct-associated
with another entity, the check fails.
I fixed this by getting the root symbol of the symbol found and doing the check
on the root symbol. This required creating a non-const version of
"GetAssociationRoot()".
Differential Revision: https://reviews.llvm.org/D92970
This patch plugs many holes in static initializer semantics, improves error
messages for default initial values and other component properties in
parameterized derived type instantiations, and cleans up several small
issues noticed during development. We now do proper scalar expansion,
folding, and type, rank, and shape conformance checking for component
default initializers in derived types and PDT instantiations.
The initial values of named constants are now guaranteed to have been folded
when installed in the symbol table, and are no longer folded or
scalar-expanded at each use in expression folding. Semantics documentation
was extended with information about the various kinds of initializations
in Fortran and when each of them are processed in the compiler.
Some necessary concomitant changes have bulked this patch out a bit:
* contextual messages attachments, which are now produced for parameterized
derived type instantiations so that the user can figure out which
instance caused a problem with a component, have been added as part
of ContextualMessages, and their implementation was debugged
* several APIs in evaluate::characteristics was changed so that a FoldingContext
is passed as an argument rather than just its intrinsic procedure table;
this affected client call sites in many files
* new tools in Evaluate/check-expression.cpp to determine when an Expr
actually is a single constant value and to validate a non-pointer
variable initializer or object component default value
* shape conformance checking has additional arguments that control
whether scalar expansion is allowed
* several now-unused functions and data members noticed and removed
* several crashes and bogus errors exposed by testing this new code
were fixed
* a -fdebug-stack-trace option to enable LLVM's stack tracing on
a crash, which might be useful in the future
TL;DR: Initialization processing does more and takes place at the right
times for all of the various kinds of things that can be initialized.
Differential Review: https://reviews.llvm.org/D92783
Fortran defines "null-init" null pointer initializers as
being function references, syntactically, that have to resolve
to calls to the intrinsic function NULL() with no actual
arguments.
Differential revision: https://reviews.llvm.org/D91657
COMPLEX negation, addition, subtraction, conversions of kind, and
equality/inequality were represented as component-wise REAL
operations. It turns out to be easier for lowering if we
do not split and recombine these COMPLEX operations, and it
avoids a potential problem with COMPLEX valued function calls
in these contexts. So add this suite of operations to the
typed expression representation in place of the component-wise
transformations, and support them in folding.
Differential revision: https://reviews.llvm.org/D91443
When comparing arrays whose shapes do not conform, the contant folding
code ran into problems trying to get the value of an extent that did not
exist. There were actually two problems. First, the routine
"CheckConformance()" was returning "true" when the compiler was unable
to get the extent of an array. Second, the function
"ApplyElementwise()" was calling "CheckConformance()" prior to folding
the elements of two arrays, but it was ignoring the return value.
Differential Revision: https://reviews.llvm.org/D91440
Avoid a spurious error message about a dummy procedure reference
in a specification expression by restructuring the handling of
use-associated and host-associated symbols.
Updated to fix a circular dependence between shared library
binaries that was introduced by the original patch.
Differential revision: https://reviews.llvm.org/D91286
Avoid a spurious error message about a dummy procedure reference
in a specification expression by restructuring the handling of
use-associated and host-associated symbols.
Differential revision: https://reviews.llvm.org/D91209
Add explicit member initializers to the declarations of
some constexpr values added in a recent patch to avoid an
apparent problem with gcc 8.2.0 with default initializers.
Differential revision: https://reviews.llvm.org/D90696
Ensure that character length is properly calculated for
actual arguments to intrinsics, and that source provenance
information is available when expression analysis calls
folding in cases where the length is invalid.
Differential revision: https://reviews.llvm.org/D90636
2 Bug fixes:
- Do not resolve procedure as intrinsic if they appeared in an
EXTERNAL attribute statement (one path was not considering this flag)
- Emit an error if a procedure resolved to be an intrinsic function
(resp. subroutine) is used as a subroutine (resp. function).
Lowering was attempted while the evaluate::Expression for the
call was missing without any errors.
1 behavior change:
- Do not implicitly resolve subroutines (resp. functions) as intrinsics
because their name is the name of an intrinsic function (resp.
subroutine). Add justification in documentation.
Reviewed By: klausler, tskeith
Differential Revision: https://reviews.llvm.org/D90049
The class IntrinsicProcTable uses the pimpl idiom and manages its own pointer-to-implementation. However, it violates the rule-of-five and does not implement a move-constructor or assignment-operator. Due to differences between compilers in implementation copy elision, these may or may not be used. Due to the missing user implementation for resource handling, using the results in runtime errors.
Fix my using `std::unique_ptr` instead of custom resource management.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D88794
Patch D88695 introduces a new local variable inside a lambda with the same name as a variable outside of it. In some of the if constexpr regions, msvc prioritizes the outer declaration and emits the error.
```
C:\Users\meinersbur\src\llvm-project\flang\lib\Evaluate\fold-implementation.h(1200): error C3493: 'context' cannot be implicitly captured because no default capture mode has been specified
```
This is fixed by giving the inner variable a different name.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D89367
In my previous implementation of the semantic checks for ASSOCIATED(), I
had neglected to check the TARGET= argument for objects to ensure that
it has either the POINTER or TARGET attributes.
I added an implementation and a test.
Differential Revision: https://reviews.llvm.org/D89717
Check INTENT(OUT)/INTENT(INOUT) constraints for actual argument
of intrinsic procedure calls.
- Adding a common::Intent field to the IntrinsicDummyArgument
in the intrinsic table.
- Propagating it to the DummyDataObject intent field so that it can
later be used in CheckExplicitDataArg semantic checks.
- Add related tests.
- Fix regression (C846 false error), C846 INTENT(OUT) rule does
not apply to intrinsic call. Propagate the information that we
are in an intrinsic call up to CheckExplicitDataArg (that is
doing this check). Still enforce C846 on intrinsics other than MOVE_ALLOC (for which
allocatable coarrays are explicitly allowed) since it's not clear it is allowed in all
intrinsics and allowing this would lead to runtime penalties in the intrinsic runtime.
Differential Revision: https://reviews.llvm.org/D89473
Calling "ASSOCATED(NULL()) was causing an internal check of the compiler to
fail.
I fixed this by changing the entry for "ASSOCIATED" in the intrinsics table to
accept "AnyPointer" which contains a new "KindCode" of "pointerType". I also
changed the function "FromActual()" to return a typeless intrinsic when called
on a pointer, which duplicates its behavior for BOZ literals. This required
changing the analysis of procedure arguments. While testing processing for
procedure arguments, I found another bad call to `CHECK()` which I fixed.
I made several other changes:
-- I implemented constant folding for ASSOCIATED().
-- I fixed handling of NULL() in relational operations.
-- I implemented semantic analysis for ASSOCIATED().
-- I noticed that the semantics for ASSOCIATED() are similar to those for
pointer assignment. So I extracted the code that pointer assignment uses
for procedure pointer compatibility to a place where it could be used by
the semantic analysis for ASSOCIATED().
-- I couldn't figure out how to make the general semantic analysis for
procedure arguments work with ASSOCIATED()'s second argument, which can
be either a pointer or a target. So I stopped using normal semantic
analysis for arguments for ASSOCIATED().
-- I added tests for all of this.
Differential Revision: https://reviews.llvm.org/D88313
The call to the binary->decimal formatter in real.cpp was cheating
by using a reinterpret_cast<> to extract its binary value.
Use a more principled and portable approach by extending the
API of evaluate::Integer<> to include ToUInt<>()/ToSInt<>()
member function templates that do the "right" thing. Retain
ToUInt64()/ToSInt64() for compatibility.
Differential revision: https://reviews.llvm.org/D89435
As usual, it's difficult to handle all different configuration in the first row,
but this one has been extensively tested
Differential Revision: https://reviews.llvm.org/D89452
- Rework the host runtime table so that it is constexpr to avoid
having to construct it and to store/propagate it.
- Make the interface simpler (remove many templates and a file)
- Enable 16bits float folding using 32bits float host runtime
- Move StaticMultimapView into its own header to use it for host
folding
Reviewed By: klausler, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D88981
CHARACTER length expressions were not always being
captured or computed as part of procedure "characteristics",
leading to test failures due to an inability to compute
memory size expressions accurately.
Differential revision: https://reviews.llvm.org/D88689
A recent MSVC work-around patch is eliciting unused variable
warnings from clang; package the lambda reference arguments
into a struct to avoid the warning.
Differential revision: https://reviews.llvm.org/D88695
This resolves an issue where the Microsoft compiler 'forgets' symbols when using constexpr in a lambda in a templated function. The symbols are:
1. The implicit lambda captures `context` and `convert`. Fix by making them explicit captures. The error message was:
```
fold-implementation.h(1220): error C2065: 'convert': undeclared identifier
```
2. The function template argument FROMCAT. Fix by storing it in a temporary constexpr variable inside the function. The error message was:
```
fold-implementation.h(1216): error C2065: 'FROMCAT': undeclared identifier
```
This patch is part of the series to make flang compilable with MS Visual Studio <http://lists.llvm.org/pipermail/flang-dev/2020-July/000448.html>.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D88504
Represent FINAL subroutines in the symbol table entries of
derived types. Enforce constraints. Update tests that have
inadvertent violations or modified messages. Added a test.
The specific procedure distinguishability checking code for generics
was used to enforce distinguishability of FINAL procedures.
(Also cleaned up some confusion and redundancy noticed in the
type compatibility infrastructure while digging into that area.)
Differential revision: https://reviews.llvm.org/D88613
SAVE statement, according to 8.6.14, must apply to the same scoping
unit, that excludes nested scoping units. For example, if the SAVE
statement is found in a MODULE, the functions contained in that module
should not inherit the SAVE attribute. I think that the code was doing
this, failing the following source:
```
MODULE pippo
SAVE
CONTAINS
PURE FUNCTION fft_stick_index( )
IMPLICIT NONE
INTEGER :: fft_stick_index
INTEGER :: mc !error: A pure subprogram may not have a variable with the SAVE attribute
END FUNCTION
END MODULE
```
Differential Revision: https://reviews.llvm.org/D88279
Fortran 2018 15.4.2.2(4)(c) says nonassumed or explicit non-constant
length parameter require explicit interface. The "nonassumed" part was
missing in f18 characteristic analysis causing CanBeCalledViaImplicitInterface
to return false for `CHARACTER(*) function foo()` like interfaces.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D88075
According to section 9.4.1, paragraph 3,
If the starting point is greater than the ending point, the substring has
length zero
But the compilers code for substring processing was failing a call to `CHECK()`
in this case. I fixed this by just setting the number of items in the
resulting string to 0 for this situation.
Differential Revision: https://reviews.llvm.org/D87799
When we define a derived type that extends another derived type, we can then
create a structure constructor that contains values for the fields of both the
child type and its parent. The compiler's internal representation of that
value contains the name of the parent type where a component name would
normally appear. This caused an assert during contant folding.
There are three cases for components that appear in structure constructors.
The first is the normal case of a component appearing in a structure
constructor for its type.
The second is a component of the parent (or grandparent) type appearing in a
structure constructor for the child type.
The third is the parent type component, which can appear in the structure
constructor of its child.
There are also cases where the component can be arrays.
I created the test case folding12.f90 that covers all of these cases and
modified the code to handle them.
Most of my changes were to the "Find()" method of the type
"StructureConstructor" where I added code to cover the second and third cases
described above. To handle these cases, I needed to create a
"StructureConstructor" for the parent type component and return it. To handle
returning a newly created "StructureConstructor", I changed the return type of
"Find()" to be "std::optional" rather than an ordinary pointer.
This change supersedes D86172.
Differential Revision: https://reviews.llvm.org/D87151
Change how generic operators and assignments are checked for
distinguishable procedures. Because of how they are invoked, available
type-bound generics and normal generics all have to be considered
together. This is different from how generic names are checked.
Move common part of checking into DistinguishabilityHelper so that it
can be used in both cases after the appropriate procedures have been
added.
Cache result of Procedure::Characterize(Symbol) in a map in
CheckHelper so that we don't have to worry about passing the
characterized Procedures around or the cost of recomputing them.
Add MakeOpName() to construct names for defined operators and assignment
for using in error messages. This eliminates the need for different
messages in those cases.
When the procedures for a defined operator or assignment are undistinguishable,
include the type name in the error message, otherwise it may be ambiguous.
Add missing check that procedures for defined operators are functions
and that their dummy arguments are INTENT(IN) or VALUE.
Differential Revision: https://reviews.llvm.org/D87341
Change the expression representation TypeParamInquiry from being
a class that's templatized on the integer KIND of its result into
a monomorphic representation that results in a SubscriptInteger
that can then be converted.
This is a minor simplification, but it's worth doing because
it is believed to also be a work-around for bugs in the MSVC
compiler with overload resolution that affect the expression
traversal framework.
Differential Revision: https://reviews.llvm.org/D86551
When a procedure name was used on the RHS of an assignment we were not
reporting the error. When one was used in an expression the error
message wasn't very good (e.g. "Operands of + must be numeric; have
INTEGER(4) and untyped").
Detect these cases in ArgumentAnalyzer and emit better messages,
depending on whether the named procedure is a function or subroutine.
Procedure names may appear as actual arguments to function and
subroutine calls so don't report errors in those cases. That is the same
case where assumed type arguments are allowed, so rename `isAssumedType_`
to `isProcedureCall_` and use that to decide if it is an error.
Differential Revision: https://reviews.llvm.org/D86107
The shape (esp. the size) of the result of a call to TRANSFER
is implemented according to the definition in the standard.
Differential Revision: https://reviews.llvm.org/D85866
Character literal substrings used as arguments were causing asserts. This
happened when the code was trying to get the DynamicType of the substring. We
were only recording the DynamicType of the Designator on which the substring
was based. For character literal substrings, the Designator was a character
literal, and we weren't handling getting its type.
I fixed this by changing the `GetType()` method for `DynamicType` to check to
see if we were getting the type of a `Substring` and calculating the type of
the substring by getting the number of bytes in an element of the string.
I also changed the test `resolve49.f90` with some tests, one of which causes
the original crash.
Differential Revision: https://reviews.llvm.org/D85908
This patch takes advantage of the directive information and tablegen generation
to replace the clauses class parse tree and in the dump parse tree sections.
Reviewed By: sscalpone
Differential Revision: https://reviews.llvm.org/D85549
This patch takes advantage of the directive information and tablegen generation
to replace the clauses class parse tree and in the dump parse tree sections.
Reviewed By: sscalpone
Differential Revision: https://reviews.llvm.org/D85549
Objects that are storage associated by EQUIVALENCE and
initialized with DATA are initialized by creating a
compiler temporary data object in the same scope,
assigning it an offset, type, and size that covers the
transitive closure of the associated initialized original
symbols, and combining their initializers into one common
initializer for the temporary.
Some problems with offset assignment of EQUIVALENCE'd objects
in COMMON were exposed and corrected, and some more error
cases are checked.
Remove obsolete function.
Small bugfix (nested implied dos).
Add a test.
Fix struct/class warning.
Differential Revision: https://reviews.llvm.org/D85560
1. Annotate the sources with constraint numbers.
2. Add tests for
*C7107 (R765) digit shall have one of the values 0 or 1.
*C7108 (R766) digit shall have one of the values 0 through 7.
*C7109 (R764) A boz-literal-constant shall appear only as a data-stmt-constant in a DATA statement, or where explicitly allowed in 16.9 as an actual argument of an intrinsic procedure.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D84504
CMPLX folding was expecting only one arguments in case X argument
is complex. This is wrong since there is also the optional KIND
argument.
Reviewed By: schweitz
Differential Revision: https://reviews.llvm.org/D84936
I fixed an assert caused by passing an empty array as the source= argument to
RESHAPE(). In the process, I noticed that there were no tests for RESHAPE(),
so I wrote a test that covers all the description in 16.9.163. In the process,
I made the error messages more consistent and descriptive. I also changed the
test to see if a reference to an intrinsic function was a constant to say that
it is a constant if it's a refererence to an invalid intrinsic. This avoids
emitting multiple messages for the same erroneous source.
Differential Revision: https://reviews.llvm.org/D84904
The intrinsic lowering facility is based on the generic intrinsic names to avoid
duplicating implementations. Specific intrinsics call are re-written to call to
the generic versions by the front-end but this cannot be done when specific intrinsics
are passed as arguments (the rewrite would give illegal/ambiguous unparsed Fortran).
Solve the issue by making the specific to generic name mapping accessible to lowering
and can be later used to generate the unrestricted intrinsic functions.
Reviewed By: schweitz
Differential Revision: https://reviews.llvm.org/D84842
Summary:
When a constant array of empty strings goes through contant folding, the result
is something that contains no bytes. If this array is passed to the intrinsic
function `RESHAPE()`, we were not handling things correctly. I fixed this by
checking for an empty destination when calling the function `CopyFrom()` on an
array of strings.
I also added a test with a couple of different examples that trigger the
problem.
Reviewers: klausler, tskeith, DavidTruby
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D84352
Fix fronted shared library builds by eliminating dependences of
the parser on other component libraries, moving some code around that
wasn't in the right library, and making some dependences
explicit in the CMakeLists.txt files. The lowering library
does not yet build as a shared library due to some undefined
names.
Reviewed By: tskeith
Differential Revision: https://reviews.llvm.org/D83515
Do not rewrite LEN(x) or x%len to the expression that specifies
the length of x when that length is not a constant expression.
Its value may have changed since the value of the expression was
first captured in the definition of the object.
Reviewed By: tskeith, sscalpone
Differential Revision: https://reviews.llvm.org/D83352
I added 'num_images()' to the list of functions that are evaluated as intrinsic. I also added a test file in flang/test/Semantics to test calls to 'num_images()'. There was a call to 'num_images()' in flang/test/Semantics/call10.f90 that expected an error, now it no longer produces an error. So I edited that file accordingly. I also edited the intrinsics unit test to add further testing of 'num_images()'.
Differential Revision: https://reviews.llvm.org/D83142
This change prepares usage of lipgmath description in lowering.
- Removes the static variable templates that were used to abstract
libpgmath description
- Move the description to pgmath.h.inc header and rework the macros
so that they can both be used to declare pgmath functions and use
them.
The way they are to be used is left to pgmath.h.inc user that
must define PGMATH_USE_XX macros that will be called for all pgmath
functions in pgmath.h.inc.
- In intrinsic-library.cpp define PGMATH_USE_XX macro callbacks in
order to capture function pointers to pgmath functions as well as
a description of their type. This will be used for constant folding
using pgmath.
- Change atan/atan2 handling to use atan2 instead of atan when there are two
arguments because it is easier to handle in the runtime description.
Also fixes lipgmath linking regression after D78215 cmake changes.
This change is motivated by the need to use a similar pgmath
description in lowering. The difference is that no function pointers will
be taken there, and instead only the function name and type are needed.
Reviewed By: schweitz, sscalpone
Differential Revision: https://reviews.llvm.org/D83051
Summary:
This patch is removing the custom enumeration for OpenMP Directives and Clauses and replace them
with the newly tablegen generated one from llvm/Frontend. This is a first patch and some will follow to share the same
infrastructure where possible. The next patch should use the clauses allowance defined in the tablegen file.
Reviewers: jdoerfert, DavidTruby, sscalpone, kiranchandramohan, ichoyjx
Reviewed By: DavidTruby, ichoyjx
Subscribers: jholewinski, cfe-commits, dblaikie, MaskRay, ymandel, ichoyjx, mgorny, yaxunl, guansong, jfb, sstefan1, aaron.ballman, llvm-commits
Tags: #llvm, #flang, #clang
Differential Revision: https://reviews.llvm.org/D82906
flang/module only contains Fortran files and one is a .h so disable
formatting on that directory.
Differential Revision: https://reviews.llvm.org/D82989
Summary:
This patch is removing the custom enumeration for OpenMP Directives and Clauses and replace them
with the newly tablegen generated one from llvm/Frontend. This is a first patch and some will follow to share the same
infrastructure where possible. The next patch should use the clauses allowance defined in the tablegen file.
Reviewers: jdoerfert, DavidTruby, sscalpone, kiranchandramohan, ichoyjx
Reviewed By: DavidTruby, ichoyjx
Subscribers: ichoyjx, mgorny, yaxunl, guansong, jfb, sstefan1, aaron.ballman, llvm-commits
Tags: #llvm, #flang
Differential Revision: https://reviews.llvm.org/D82906
Treat function result like dummy argument: a SAVE statement without an
entity-list does not make it saved.
Differential Revision: https://reviews.llvm.org/D82309
Implement shape analysis for the result of the MATMUL
generic transformational intrinsic function, based on
the shapes of its arguments. Correct the names of the
arguments to match the standard, too.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D82250
Implement rest of DATA statement semantics and conversion of
DATA statement initializations into static initializers of
objects in their symbol table entries.
Reviewed By: tskeith, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D82207
Rolls up small changes across the frontend to prepare for the large
forthcoming patch (part 4/4) that completes DATA statement processing
via conversion to initializers.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D82137
Summary:
Defines a representation for the initialized memory image of
a variable. This image is populated by DATA statement
processing as designator elements are put into correspondence
with values, then converted into an initializer in the symbol
table so that lowering can pass the initial image to the
code generator.
Reviewers: tskeith, PeteSteinfeld, sscalpone, jdoerfert, DavidTruby
Reviewed By: tskeith
Subscribers: mgorny, llvm-commits, flang-commits
Tags: #flang, #llvm
Differential Revision: https://reviews.llvm.org/D82131
Summary:
Add code to resolve constant Designators at compilation time
into a base Symbol, byte offset, and field size. This is used in
later DATA statement processing to identify the static storage being
initialized by each object in a DATA statement. Also implement
the reverse mapping so that Designators can be reconstructed for
use in error messages about (e.g.) duplicate initializers.
Reviewers: tskeith, PeteSteinfeld, sscalpone, jdoerfert, DavidTruby
Reviewed By: PeteSteinfeld
Subscribers: mgorny, llvm-commits, flang-commits
Tags: #flang, #llvm
Differential Revision: https://reviews.llvm.org/D82125
Summary:
This patch changes speficic extremum functions rewrite to generic MIN/MAX.
It applies to AMAX0, AMIN0, AMAX1, AMIN1, MAX0, MIN0, MAX1, MIN1, DMAX1,
and DMIN1.
- Do not re-write specific extremums to MAX/MIN in intrinsic Probe and let
folding rewrite it and introduc the conversion on the MIN/MAX result.
- Also make operand promotion explicit in MIN/MAX folding.
For instance, after this patch:
AMAX0(int8, int4) is rewritten to REAL(MAX(int8, INT(int4, 8)))
All this care is to avoid rewritting it to MAX(REAL(int8), REAL(int4))
that may not always be numerically equivalent to the first rewrite.
Reviewers: klausler, schweitz, sscalpone, jdoerfert, DavidTruby
Reviewed By: klausler, schweitz
Subscribers: llvm-commits, flang-commits
Tags: #flang, #llvm
Differential Revision: https://reviews.llvm.org/D81940
Summary:
Using a forward reference to define a `len` parameter causes a crash.
The underlying cause was that a previously declared type had an
erroneous expression for its `LEN` param value. When this expression
was referenced to evaluate a subsequent expression, bad things happened.
I fixed this by putting in code to detect this case.
Reviewers: tskeith, klausler, DavidTruby
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D80593
Summary:
Fortran::evaluate::IsConstantExpr did not check that the numerator
was a constant expression. This patch fixes the issue.
Reviewers: DavidTruby, klausler, schweitz, PeteSteinfeld, jdoerfert, sscalpone
Reviewed By: klausler, PeteSteinfeld, sscalpone
Subscribers: llvm-commits
Tags: #llvm, #flang
Differential Revision: https://reviews.llvm.org/D81096
Summary
- Implemented C876, C877
- Fixed IsConstantExpr to check C879
- Fixed bugs in few test cases - data01.f90, block-data01.f90,
pre-fir-tree02.f90
- Modified implementation of C8106 to identify all automatic objects
and modified equivalence01.f90 to reflect the changes
Differential Revision: https://reviews.llvm.org/D78424
Summary:
Some Symbol-related functions used in Evaluate were moved to
Evaluate/tools.h. This includes changing some member functions that were
replaced by non-member functions `IsDummy`, `GetUsedModule`, and
`CountLenParameters`.
Some member functions were made inline in `Scope`, `Symbol`,
`ArraySpec`, and `DeclTypeSpec`. The definitions were preceded by a
comment explaining why they are inline.
`IsConstantShape` was expanded inline in `IsDescriptor` because it isn't
used anywhere else
After this change, at least when compiling with clang on macos,
`libFortranEvaluate.a` has no undefined symbols that are satisfied by
`libFortranSemantics.a`.
Reviewers: klausler, PeteSteinfeld, sscalpone, jdoerfert, DavidTruby
Reviewed By: PeteSteinfeld
Subscribers: llvm-commits
Tags: #flang, #llvm
Differential Revision: https://reviews.llvm.org/D80762
Summary:
Many of these were already implemented, and I just annotated the tests and/or
the code.
C752 was a simple check to verify that CONTIGUOUS components are arrays with
C754 proved to be virtually identical to C750 that I implemented previously.
This caused me to remove the distinction between specification expressions for
type parameters and bounds expressions that I'd previously created.
the POINTER attribute.
I also changed the error messages to specify that errors in specification
expressions could arise from either bad derived type components or type
parameters.
In cases where we detect a type param that was not declared, I created a symbol
marked as erroneous. That avoids subsequent semantic process for expressions
containing the symbol. This change caused me to adjust tests resolve33.f90 and
resolve34.f90. Also, I avoided putting out error messages for erroneous type
param symbols in `OkToAddComponent()` in resolve-names.cpp and in
`EvaluateParameters()`, type.cpp.
C756 checks that procedure components have the POINTER attribute.
Reviewers: tskeith, klausler, DavidTruby
Subscribers: llvm-commits
Tags: #llvm, #flang
Differential Revision: https://reviews.llvm.org/D79798
Summary:
Initially on github I worked on semantic checks.Then I tried some compile-time
test of the rank value, they were failing as there were no symbols
generated for them inside SELECT RANK's scope.So I went further to
add new symbol in each scope, also added the respective 'rank: '
field for a symbol when we dump the symboltable. I added a field to
keep track of the rank in AssocEntityDetails class.This caused shape
analysis framework to become inconsistent. So shape analysis framework
was updated to handle this new representation.
* I added more tests for above changes.
* On phabricator I addressed some minor changes.
* Lastly I worked on review comments.
Reviewers: klausler,sscalpone,DavidTruby,kiranchandramohan,tskeith,anchu-rajendran,kiranktp
Reviewed By:klausler, DavidTruby, tskeith
Subscribers:#flang-commits, #llvm-commits
Tags: #flang, #llvm
Differential Revision: https://reviews.llvm.org/D78623
IsDescriptor was returning false for a component whose shape depended
on a length parameter. Change it to return true for any array with
non-constant bounds.
Differential Revision: https://reviews.llvm.org/D79349
Summary: I updated the code that produces the message and the associated test.
Reviewers: sscalpone, DavidTruby, kiranchandramohan
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D79514
Summary: I updated the code that produces the message and the associated test.
Reviewers: sscalpone, DavidTruby
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D79514
Summary:
Most of these checks were already implemented, and I just added references to
them to the code and tests. Also, much of this code was already
reviewed in the old flang/f18 GitHub repository, but I didn't get to
merge it before we switched repositories.
I implemented the check for C747 to not allow coarray components in derived
types that are of type C_PTR, C_FUNPTR, or type TEAM_TYPE.
I implemented the check for C748 that requires a data component whose type has
a coarray ultimate component to be a nonpointer, nonallocatable scalar and not
be a coarray.
I implemented the check for C750 that adds additional restrictions to the
bounds expressions of a derived type component that's an array.
These bounds expressions are sepcification expressions as defined in
10.1.11. There was already code in lib/Evaluate/check-expression.cpp to
check semantics for specification expressions, but it did not check for
the extra requirements of C750.
C750 prohibits specification functions, the intrinsic functions
ALLOCATED, ASSOCIATED, EXTENDS_TYPE_OF, PRESENT, and SAME_TYPE_AS. It
also requires every specification inquiry reference to be a constant
expression, and requires that the value of the bound not depend on the
value of a variable.
To implement these additional checks, I added code to the intrinsic proc
table to get the intrinsic class of a procedure. I also added an
enumeration to distinguish between specification expressions for
derived type component bounds versus for type parameters. I then
changed the code to pass an enumeration value to
"CheckSpecificationExpr()" to indicate that the expression was a bounds
expression and used this value to determine whether to emit an error
message when violations of C750 are found.
I changed the implementation of IsPureProcedure() to handle statement
functions and changed some references in the code that tested for the
PURE attribute to call IsPureProcedure().
I also fixed some unrelated tests that got new errors when I implemented these
new checks.
Reviewers: tskeith, DavidTruby, sscalpone
Subscribers: jfb, llvm-commits
Tags: #llvm, #flang
Differential Revision: https://reviews.llvm.org/D79263
Summary:
Updates recent work on DATA statement semantic checking in
flang/lib/Semantics/check-data.{h,cpp} to use the compiler's
internal representation for typed expressions rather than working
on the raw parse tree. Saves the analyzed expressions for DATA
statement values as parse tree decorations because they'll soon be
needed in lowering. Corrects wording of some error messages.
Fixes a bug in constant expression checking: structure constructors
are not constant expressions if they set an allocatable component
to anything other than NULL.
Includes infrastructure changes to make this work, some renaming
to reflect the fact that the implied DO loop indices tracked by
expression analysis are not (just) from array constructors, remove
some dead code, and improve some comments.
Reviewers: tskeith, sscalpone, jdoerfert, DavidTruby, anchu-rajendran, schweitz
Reviewed By: tskeith, anchu-rajendran, schweitz
Subscribers: llvm-commits, flang-commits
Tags: #flang, #llvm
Differential Revision: https://reviews.llvm.org/D78834
Summary:
Add size and offset properties to symbols, representing their byte size
and offset within their enclosing scope.
Add size and align properties to scopes so that they are available for
scopes representing derived types.
Add ComputeOffsets pass over the symbol table to fill in those fields.
Compute descriptor size based on rank and length parameters. Extract
DerivedTypeSpec::NumLengthParameters from DynamicType::RequiresDescriptor
to share the code.
Add Scope::GetSymbols to get symbols in canonical order.
compute-offsets.cpp and mod-file.cpp both need to process symbols in the
order in which they are declared. Move the collecting of those symbols
into Scope so that it can be shared.
Add symbol size and offset to output of `-fdebug-dump-symbols` and use
that in some tests.
Still to do:
- make size and alignment rules configurable based on target
- use offsets to check EQUIVALENCE statements
Differential Revision: https://reviews.llvm.org/D78680
Patch D78215 changes various dependencies in the CMakeLists.txt. This
results in error while compiling. This patch fixes the issue.
Reviewers: DavidTruby
Differential Revision: https://reviews.llvm.org/D78340
When building flang with LLVM HEAD, the unittests fail to link with ld.bfd or
ld.gold due to a linker ordering issue. Adding libSemantics as a dependency to
libEvaluate seems to fix that issue.
Reviewed at: https://github.com/flang-compiler/f18/pull/1104
There is no printf formatting string for std::int64_t. Instead we have
to cast to std::intmax_t and use `%jd`. This change simplifies that by
automatically converting std::int64_t to std::intmax_t when formatting
messages.
Original-commit: flang-compiler/f18@8a2343dfff
Reviewed-on: https://github.com/flang-compiler/f18/pull/1101
Tree-same-pre-rewrite: false