Semantics is rejecting valid programs with NULL() actual arguments
to generic interfaces, including user-defined operators. Subclause
16.9.144(para 6) makes clear that NULL() can be a valid actual
argument to a generic interface so long as it does not produce
ambiguity. This patch handles those cases, revises existing
tests, and adjust an error message about NULL() operands to
appear less like a blanket prohibition.
Differential Revision: https://reviews.llvm.org/D111850
Rearrange the contents of __builtin_* module files a little and
make sure that semantics implicitly USEs the module __Fortran_builtins
before processing each source file. This ensures that the special derived
types for TEAM_TYPE, EVENT_TYPE, LOCK_TYPE, &c. exist in the symbol table
where they will be available for use in coarray intrinsic function
processing.
Update IsTeamType() to exploit access to the __Fortran_builtins
module rather than applying ad hoc name tests. Move it and some
other utilities from Semantics/tools.* to Evaluate/tools.* to make
them available to intrinsics processing.
Add/correct the intrinsic table definitions for GET_TEAM, TEAM_NUMBER,
and THIS_IMAGE to exercise the built-in TEAM_TYPE as an argument and
as a result.
Add/correct/extend tests accordingly.
Differential Revision: https://reviews.llvm.org/D110356
A defined assignment subroutine invoked in the context of a WHERE
statement or construct must necessarily be elemental (C1032).
Differential Revision: https://reviews.llvm.org/D109932
Improve checking for NULL() and NULL(MOLD=) when used as
variables and expressions outside the few contexts where
a disassociated pointer can be valid. There were both
inappropriate errors and missing checks.
Differential Revision: https://reviews.llvm.org/D109905
The index of an implied DO loop in a DATA statement or array
constructor is defined by Fortran 2018 to have scope over its
implied DO loop. This definition is unfortunate, because it
requires the implied DO loop's bounds expressions to be in the
scope of the index variable. Consequently, in code like
integer, parameter :: j = 5
real, save :: a(5) = [(j, j=1, j)]
the upper bound of the loop is a reference to the index variable,
not the parameter in the enclosing scope.
This patch limits the scope of the index variable to the "body"
of the implied DO loop as one would naturally expect, with a warning.
I would have preferred to make this a hard error, but most Fortran
compilers treat this case as f18 now does. If the standard
were to be fixed, the warning could be made optional.
Differential Revision: https://reviews.llvm.org/D108595
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
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
When a function is called in a specification expression, it must be
sufficiently defined, and cannot be a recursive call (10.1.11(5)).
The best fix for this is to change the contract for the procedure
characterization infrastructure to catch and report such errors,
and to guarantee that it does emit errors on failed characterizations.
Some call sites were adjusted to avoid cascades.
Differential Revision: https://reviews.llvm.org/D104330
When a program attempts to put something like a subprogram
into an array constructor, emit an error rather than crashing.
Differential Revision: https://reviews.llvm.org/D104336
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
When a procedure pointer with no interface is called by a
function reference, complain about the lack.
Differential Revision: https://reviews.llvm.org/D103573
In something like "ASSOCIATE(X=>T(1))", the "T(1)" is parsed
as a Variable because it looks like a function reference or
array reference; if it turns out to be a structure constructor,
which is something we can't know until we're able to attempt
generic interface resolution in semantics, the parse tree needs
to be fixed up by replacing the Variable with an Expr.
The compiler could already do this for putative function references
encapsulated as Exprs, so this patch moves some code around and
adds parser::Selector to the overloads of expression analysis.
Differential Revision: https://reviews.llvm.org/D103572
The constexpr-capable class evaluate::DynamicType represented
CHARACTER length only with a nullable pointer into the declared
parameters of types in the symbol table, which works fine for
anything with a declaration but turns out to not suffice to
describe the results of the ACHAR() and CHAR() intrinsic
functions. So extend DynamicType to also accommodate known
constant CHARACTER lengths, too; use them for ACHAR & CHAR;
clean up several use sites and fix regressions found in test.
Differential Revision: https://reviews.llvm.org/D103571
As a benign extension common to other Fortran compilers,
accept BOZ literals in array constructors w/o explicit
types, treating them as integers.
Differential Revision: https://reviews.llvm.org/D103569
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
We were not correctly handling structure constructors that had forward
references to parameterized derived types. I harvested the code that checks
for forward references that was used during analysis of function call
expressions and called it from there and also called it during the
analysis of structure constructors.
I also added a test that will produce an internal error without this change.
Differential Revision: https://reviews.llvm.org/D101330
For pernicious test cases with explicit non-constant actual
type parameter expressions in components, e.g.:
type :: t(k)
integer, kind :: k
type(t(k+1)), pointer :: p
end type
we should detect the infinite recursion and complain rather
than looping until the stack overflows.
Differential Revision: https://reviews.llvm.org/D100065
`parser::AllocateObject` and `parser::PointerObject` can be represented
as typed expressions once analyzed. This simplifies the work for parse-tree
consumers that work with typed expressions to deal with allocatable and
pointer objects such as lowering.
This change also makes it easier to add typedExpr in the future by
automatically handling nodes that have this member when possible.
Changes:
- Add a `mutable TypedExpr typedExpr` field to `parser::PointerObject` and `parser::AllocateObject`.
- Add a `parser::HasTypedExpr<T>` helper to better share code relating to typedExpr in the parse tree.
- Add hooks in `semantics::ExprChecker` for AllocateObject and PointerObject nodes, and use
ExprOrVariable on it to analyze and set the tyedExpr field during
expression analysis. This required adding overloads for `AssumedTypeDummy`.
- Update check-nullify.cpp and check-deallocate.cpp to not re-analyze the StructureComponent but to
use the typedExpr field instead.
- Update dump/unparse to use HasTypedExpr and use the typedExpr when there is one.
Differential Revision: https://reviews.llvm.org/D98256
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
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
When accessing a specific procedure of a USE-associated generic
interface, we need to allow for the case in which that specific
procedure has the same name as the generic when testing for
its availability in the current scope.
Differential Revision: https://reviews.llvm.org/D96467
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
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
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
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
When comparing LOGICAL operands using ".eq." or ".ne." we were not
guiding users to the ".eqv." and ".neqv." operations.
Differential Revision: https://reviews.llvm.org/D91736
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
When the bounds of an implied DO loop in an array constructor are
constant, the index variable of that loop is considered a constant
expression and can be used as such in the items in the value list
of the implied DO loop. Since the KIND type parameter values of items
in the value list can depend on the various values taken by such an
index, it is not possible to represent those values with a single
typed expression. So implement such loops by taking multiple passes
over the parse tree of the implied DO loop instead.
Differential revision: https://reviews.llvm.org/D90494
I added a test to verify that the associated symbol did not have errors before
doing the anaylsis of a call to a component ref along with a test that
triggers the original problem.
Differential Revision: https://reviews.llvm.org/D90074
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 semantics pass currently checks for several constraints
that apply to the use of whole assumed-size arrays in various
contexts, but C1002 wasn't really implemented. This patch
implements C1002 by disallowing the use of whole assumed-size
arrays in expressions and variables unless specifically
allowed by the context. This centralizes the error reporting,
which has been improved with a link to the array's declaration.
Differential revision: https://reviews.llvm.org/D88691
A type name in an IMPLICIT declaration that was later used in a PARAMETER
statement caused problems because the default symbol scope had not yet been
initialized. I avoided dereferencing in the situation where the default scope
was uninitialized and added a test that triggers the problem.
Also, once I corrected the bad dereference, the compiler was putting out
misleading error messages. The underlying error us due to violating section
7.5.10, paragraph 4, which states:
A structure constructor shall not appear before the referenced type is
defined.
I fixed this by testing to see if a type that is used in a structure
constructor is forward referenced.
Differential Revision: https://reviews.llvm.org/D87535
Change the analyzed form of type-bound assignment to match that of call
statements. Resolve the binding name to a specific subprogram when
possible by using `GetBindingResolution`. Otherwise leave it as a
type-bound procedure call.
Differential Revision: https://reviews.llvm.org/D87541
Conformance checking of the shapes of the operands of
array expressions can't, of course, always be done at
compilation time; but when the shapes are known and
nonconformable, we should catch the errors that we can.
Differential Revision: https://reviews.llvm.org/D86887
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 an error is associated with a symbol, it was marked with a flag
from Symbol::Flag. The problem with that is that you need a mutable
symbol to do that. Instead, store the set of error symbols in the
SemanticsContext. This allows for some const_casts to be eliminated.
Also, improve the internal error that occurs if SetError is called
but no fatal error has been reported.
Differential Revision: https://reviews.llvm.org/D86740
A specification expression can reference an implicitly declared variable
in the host procedure. Because we have to process specification parts
before execution parts, this may be the first time we encounter the
variable. We were assuming the variable was implicitly declared in the
scope where it was encountered, leading to an error because local
variables may not be referenced in specification expressions.
The fix is to tentatively create the implicit variable in the host
procedure because that is the only way the specification expression can
be valid. We mark it with the flag `ImplicitOrError` to indicate that
either it must be implicitly defined in the host (by being mentioned in
the execution part) or else its use turned out to be an error.
We need to apply the implicit type rules of the host, which requires
some changes to implicit typing.
Variables in common blocks are allowed to appear in specification expressions
(because they are not locals) but the common block definition may not appear
until after their use. To handle this we create common block symbols and object
entities for each common block object during the `PreSpecificationConstruct`
pass. This allows us to remove the corresponding code in the main visitor and
`commonBlockInfo_.curr`. The change in order of processing causes some
different error messages to be emitted.
Some cleanup is included with this change:
- In `ExpressionAnalyzer`, if an unresolved name is encountered but
no error has been reported, emit an internal error.
- Change `ImplicitRulesVisitor` to hide the `ImplicitRules` object
that implements it. Change the interface to pass in names rather
than having to get the first character of the name.
- Change `DeclareObjectEntity` to have the `attrs` argument default
to an empty set; that is the typical case.
- In `Pre(parser::SpecificationPart)` use "structured bindings" to
give names to the pieces that make up a specification-part.
- Enhance `parser::Unwrap` to unwrap `Statement` and `UnlabeledStatement`
and make use of that in PreSpecificationConstruct.
Differential Revision: https://reviews.llvm.org/D86322
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
If a bound of a subscript triplet is present but fails to analyze
due to an error, return nullopt rather than returning a Triplet with
that bound missing. This is so we can distinguish an absent bound from
an erroneous one and avoid spurious errors.
Differential Revision: https://reviews.llvm.org/D85672
In the example below we were producing the error message
"Assignment to constant 'f' is not allowed":
```
function f() result(r)
f = 1.0
end
```
This changes it to a more helpful message when the LHS is a subprogram
name and also mentions the function result name when it's a function.
Differential Revision: https://reviews.llvm.org/D85483
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
Summary:
Expressions like `iVar==z'fe'` were causing an assertion error because
the `Relate()` function in `Evaluate/tools.cpp` that processes
relational operators didn't deal with BOZ literals, which are typeless.
I fixed this by checking to see if the operands are BOZ literals. If
so, if the other operand is REAL, I convert them to REAL. Otherwise, I convert
them to integers with default kind.
I also added a test to resolve63.f90 that triggers the problem.
Reviewers: tskeith, DavidTruby
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D83917