+ Fix issue 589.
+ Catch empty subscript list in array reference
In name resolution, when skimming through the execution statement of a
function, calls to the result symbol should not trigger the conversion
of this symbol to a function symbol. The result is a data object and
cannot be called unless it was explictly declared to be a procedure
pointer.
Notably, recursive function calls cannot be made if RESULT was not used.
The symbol is prevented from being transformed into a function
symbol by transforming it into an object before skimming through the
executable statement. This is done after processing all the
specifications so that if the result actually is a procedure pointer,
the call to `ConvertToObjectEntity` introduced by this commit will
not convert it to an object by mistake.
This commit also introduce a check when fixing misparsed function
reference into array reference to verify the array reference has
array subscripts. Currently this went uncaught. It is not possible
to complain later in expressions because the subscript list of
expression might be empty for unrelated error recovery reasons
(e.g. if an entity of the wrong type appeared as susbcript).
Add related tests.
Original-commit: flang-compiler/f18@2fd8b65f58
Reviewed-on: https://github.com/flang-compiler/f18/pull/631
Tree-same-pre-rewrite: false
After fixing 594, it appears there were issues in
FindUltimateComponent that was considering type bound
procedure as components.
This commit fixes and beef-up the component visitation by making a visitor
class for it. The main advantage of making it an class vs functions is that
it is possible to get the component chain to the result component for better
feedback for the user.
The framework allow a single place to define/handle what ultimate, direct and
potential components are.
Original-commit: flang-compiler/f18@d84821a1d6
Reviewed-on: https://github.com/flang-compiler/f18/pull/607
Tree-same-pre-rewrite: false
- resolve-names.cc: I reworded the message when a name appears in a
locality-spec when a name is used that cannot appear in a variable
definition context.
- tools.cc: I removed the unused functions ```IsValueDummy()``` and
```IsModifiable()```. I made the function ```GetAssociatedVariable()```
static. I cleaned up the code in ```GetAssociationRoot()```. I cleaned up
the code in ```IsOrContainsEventOrLockComponent()```. I added a TODO to
```WhyNotModifiable()``` and made some other improvements to it.
- tools.h: Removed some deleted and unnecessary functions.
- I fixed up a couple of tests related to the changes in error messages.
Original-commit: flang-compiler/f18@47da8ff9c8
Reviewed-on: https://github.com/flang-compiler/f18/pull/596
- expression.cc - fixed an error message. This required changing the tests
structconst0[3,4].f90
- tools.[h,cc] - Added a new function called ```WhyNotModifiable()``` to see
if a name can be modified. This function returns a string that describes why
the name cannot be modified. I changed the existing function
```IsModifiable()``` to call ```WhyNotModifiable()```. I fixed and
restructured the code for ```GetAssociationRoot()```. This involved creating
the mutually recursive function ```GetAssociatedVariable()```. I added a
check to see if a name is an INTENT(IN) dummy argument to the function
```IsVariableName()```.
- resolve-names.cc - Wrote the function ```SayWithReason()``` that allows an
arbitrary message to be added to an existing message. I changed the code in
```PassesLocalityChecks()``` to call the new function ```WhyNotModifiable()```
to get the specifics of why a variable name cannot be used in a variable
modification context and then call the new function ```SayWithReason()``` to
report the error. I also cleaned up the code as per Jean's suggestion.
Original-commit: flang-compiler/f18@8a2f4bdfd2
Reviewed-on: https://github.com/flang-compiler/f18/pull/596
Tree-same-pre-rewrite: false
Specifically, these changes enforce the last sentence of the constraint, which
prohibits names that cannot appear in a variable definition context from
appearing in a locality-spec. Here are the details.
- Created the function "IsModifiableName" to return "true" when its parameter
is the name of a variable that can appear in a variable definition context.
- Created the function "GetAssociationRoot" to follow construct associations
to potentially get to an underlying variable. This function is similar to
the existing "GetUltimate" function that follows use associations and host
associations. One difference is that "GetAssociationRoot" requires access
to the types "MaybeExpr" and "SomeExpr", which makes is inappropriate to put
into symbol.cc, which is where "GetUltimate" lives. Perhaps we should move
"GetUltimate" to tools.[h,cc].
- Generalized the functions "IsPureFunction" to "IsPureProcedure" since either
a pure function or subroutine can provide a context for variables that
cannot be modified. Changed "FindPureFunctionContaining" to
"FindPureProcedueContaining" to go along with this.
- Added the function "IsExternalInPureContext" to detect the case where a
nominally pure procedure potentially modifies a variable.
- Created the function "IsOrContainsEventOrLockComponent" to detect variables
that either are of EVENT_TYPE or LOCK_TYPE or contain components of these
types. Such variables cannot appear in variable definition contexts.
- Added the test resolve56.f90 to test most of these conditions. Note that I
only tested the new code from the perspective of locality-specs.
Original-commit: flang-compiler/f18@c9d2507b74
Reviewed-on: https://github.com/flang-compiler/f18/pull/596
Tree-same-pre-rewrite: false
In `OrderParameterNames` and `OrderParameterDeclarations` it was
always true that `this == &type.get<DerivedTypeDetails>()` which
meant that `this` was redundant.
So convert them to non-member functions in `tools.h` that get the
details from the symbol passed in. This makes life simpler for the
callers.
Original-commit: flang-compiler/f18@81710d4e6e
Reviewed-on: https://github.com/flang-compiler/f18/pull/559
Move these functions from scope.cc, symbol.cc, type.cc into tools.cc:
Scope::FindOrInstantiateDerivedType
Scope::InstantiateDerivedType
Scope::InstantiateIntrinsicType
Symbol::Instantiate
DerivedTypeSpec::ProcessParameterExpressions
DerivedTypeSpec::Instantiate
This eliminates some dependencies in these files on SemanticsContext,
FoldingContext, etc.
It also allows three of the functions to be private to tools.cc
because they are only called from the others.
Original-commit: flang-compiler/f18@48c6efbf95
Reviewed-on: https://github.com/flang-compiler/f18/pull/559
Tree-same-pre-rewrite: false
These changes implement most of the requirements for C1128, which says: "A
variable-name that appears in a LOCAL or LOCAL_INIT locality-spec shall not
have the ALLOCATABLE; INTENT (IN); or OPTIONAL attribute; shall not be of
finalizable type; shall not be a nonpointer polymorphic dummy argument; and
shall not be a coarray or an assumed-size array. A variable-name that is not
permitted to appear in a variable definition context shall not appear in a
LOCAL or LOCAL_INIT locality-spec."
The changes do not implement the checking required to determine whether a
variable can appear in a "variable definition context".
Here's a summary of the changes:
- I created the function 'PassesLocalityChecks()' to enforce C1128 along with
C1124, C1125, and C1126.
- I cleaned up the code to check if a type or symbol is a coarray.
- I added functions to tools.[h,cc] to test if a symbol is OPTIONAL, INTENT
IN, finalizable, a coarray, or an assumed size array. Should these be
member functions of the type "Symbol"?
- Since I changed one of the locality related error messages, I needed to
change the test resolve35.f90.
- I added the test resolve55.f90 to test all of the checks implemented in this
update.
Original-commit: flang-compiler/f18@4ca5d090b9
Reviewed-on: https://github.com/flang-compiler/f18/pull/542
Tree-same-pre-rewrite: false
The passed-object dummy argument cannot be checked until the
interfaces of contained subprograms are known. To accomplish this,
add `FinishSpecificationPart` pass to run after all specification
parts have been analyzed but before any of the execution parts.
This visits all derived types defined in each scope and performs
the checks on each procedure component and procedure binding.
Add a flag to `ParamValue` to distinguish kind from len parameters.
Fix some tests that had errors we now detect.
Original-commit: flang-compiler/f18@4789643c5b
Reviewed-on: https://github.com/flang-compiler/f18/pull/521
Collect sets of `parser::EquivalenceObject` to process at the end of
the specification part. This is so that names mentioned in the
EQUIVALENCE statement don't trigger implicit declarations.
The `EquivalenceSets` class performs most of the numerous checks
on objects that can be in equivalence sets at all and objects that
can be in them together. It also merges sets when the same object
appears in more than one.
Once equivalence sets are checked they are added to the `Scope`.
Further checks will be necessary after the size and alignment of
variables are computed.
Add `FindUltimateComponent` to simplify checks on ultimate components
of derived types. Use it to implement `HasCoarrayUltimateComponent`
and checks on equivalence objects.
Make `ExpressionAnalyzer::Analyze(Designator)` public so that
`parser::EquivalenceObject` can be analyzed.
Add `GetDefaultKind`, `doublePrecisionKind`, and `quadPrecisionKind`
to `SemanticsContext` so that `defaultKinds_` does not need to be
accessed directly.
Original-commit: flang-compiler/f18@1cc898e5b8
Reviewed-on: https://github.com/flang-compiler/f18/pull/494
Tree-same-pre-rewrite: false
When an error occurs in name resolution, continue semantic processing
in order to detect other errors. This means we can no longer assume
that every `parser::Name` has a symbol even after name resolution
completes. In `RewriteMutator`, only report internal error for unresolved
symbol if there have been no fatal errors.
Add `Error` flag to `Symbol` to indicate that an error occcurred related
to it. Once we report an error about a symbol we should avoid reporting
any more to prevent cascading errors. Add `HasError()` and `SetError()`
to simplify working with this flag.
Change some places that we assume that a `parser::Name` has a non-null
symbol. There are probably more.
`resolve-names.cc`: Set the `Error` flag when we report a fatal error
related to a symbol. (This requires making some symbols non-const.)
Remove `CheckScalarIntegerType()` as `ExprChecker` will take care of
those constraints if they are expressed in the parse tree. One exception
to that is the name in a `ConcurrentControl`. Explicitly perform that
check using `EvaluateExpr()` and constraint classes so we get consistent
error messages.
In expression analysis, when a constraint is violated (like `Scalar<>`
or `Integer<>`), reset the wrapped expression so that we don't assume it
is valid. A `GenericExprWrapper` holding a std::nullopt indicates error.
Change `EnforceTypeConstraint()` to return false when the constraint
fails to enable this.
check-do-concurrent.cc: Reorganize the Gather*VariableNames functions
into one to simplify the task of filtering out unresolved names. Remove
`CheckNoDuplicates()` and `CheckNoCollisions()` as those checks is
already done in name resolution when the names are added to the scope.
Original-commit: flang-compiler/f18@bcdb679405
Reviewed-on: https://github.com/flang-compiler/f18/pull/429
Tree-same-pre-rewrite: false
When an Expr or Variable is analyzed, always fill in a GenericExprWrapper
for it. That now holds the result of expression analysis which is
std::nullopt when there is an error.
After the ExprChecker pass has finished, the typedExpr data member of
Variables and top-level Exprs should be filled in. Assert that is the
case when we access them.
Original-commit: flang-compiler/f18@192a4e0855
Reviewed-on: https://github.com/flang-compiler/f18/pull/424
Tree-same-pre-rewrite: false
Use GetExpr in checker classes to get analyzed expressions out of parse
tree nodes. Don't assume that they are always present. Change the
utility functions in tools.h to use SomeExpr rather than
GenericExprWrapper.
Original-commit: flang-compiler/f18@594e30d462
Reviewed-on: https://github.com/flang-compiler/f18/pull/422
Tree-same-pre-rewrite: false
Add typedExpr data member to Variable like that in Expr.
When expression analysis analyzed a Variable it stores the
resulting evaluate::Expr there.
Add GetExpr overloads in semantics/tools.h for using in statement
semantics. It gets an evaluate::Expr from an Expr, Variable, or
wrapper around one of those. It returns a const pointer so that
clients cannot modify the cached expression (and copies do not
have to be made).
Change CoarrayChecker to make use of GetExpr. It will eventually
replace all references to typedExpr in statement semantics.
Original-commit: flang-compiler/f18@b02a41efe1
Reviewed-on: https://github.com/flang-compiler/f18/pull/422
Tree-same-pre-rewrite: false
This commit introduces a new checker (StopChecker) for STOP
and ERROR STOP Fortran statements along with a test code.
Signed-off-by: Paul Osmialowski <pawel.osmialowski@arm.com>
Original-commit: flang-compiler/f18@c554174562
Reviewed-on: https://github.com/flang-compiler/f18/pull/367
Tree-same-pre-rewrite: false
When analyzing a function call in an expression we weren't properly
recognizing a ProcedureDesignator that was the name of an internal
or module function, i.e. a symbol with SubprogramDetails.
The fix is to add IsProcedure to identify symbols that correspond
to procedures. IsFunction and GetType also need to be extended to
handle this case.
Fixesflang-compiler/f18#391.
Original-commit: flang-compiler/f18@f165f8d38c
Reviewed-on: https://github.com/flang-compiler/f18/pull/417
Tree-same-pre-rewrite: false
A simple name in a `Designator` is always parsed as a `DataRef`, not
an `ObjectName`. So remove that alternative.
`StmtFunctionStmt::ConvertToAssignment` was creating a `Designator` with
that alternative: change it to do the same thing as the parser.
Add `GetSimpleName` utility functions to check if an `Expr` or `Variable`
represents a simple name. Many of the places that checked for `ObjectName`
in `Designator` are trying to do that.
Clean up includes and forward declarations in `tools.h`.
Original-commit: flang-compiler/f18@97d44de7b1
Reviewed-on: https://github.com/flang-compiler/f18/pull/410
legality check is up to the user; however, some checks could
be done at compile time and others at runtime. We choose to
skip any checking at compile time because it would not be
complete.
Note the instantiation of ExtractDataRef in expressions.cc.
This instantiation satifies the reference in check-nullify.cc
because expression.h just has a declaration of ExtractDataRef
instead of the definition.
Original-commit: flang-compiler/f18@b7199219fb
Reviewed-on: https://github.com/flang-compiler/f18/pull/388
Tree-same-pre-rewrite: false