We're emitting a bogus semantic error message about an actual argument
being undefinable when associating LOCK_TYPE, EVENT_TYPE, and someday
NOTIFY_TYPE with an INTENT(IN OUT) dummy argument. These types indeed
make many definition contexts invalid, and the actual argument
associated with an INTENT(IN OUT) dummy argument must indeed be
definable, but the argument association itself is not a problem.
(This is a big patch, but it's nearly an NFC. No test results have
changed and all Fortran tests in the LLVM test suites work as expected.)
Allow a parser::Message for a warning to be marked with the
common::LanguageFeature or common::UsageWarning that controls it. This
will allow a later patch to add hooks whereby a driver will be able to
decorate warning messages with the names of its options that enable each
particular warning, and to add hooks whereby a driver can map those
enumerators by name to command-line options that enable/disable the
language feature and enable/disable the messages.
The default settings in the constructor for LanguageFeatureControl were
moved from its header file into its C++ source file.
Hooks for a driver to use to map the name of a feature or warning to its
enumerator were also added.
To simplify the tagging of warnings with their corresponding language
feature or usage warning, to ensure that they are properly controlled by
ShouldWarn(), and to ensure that warnings never issue at code sites in
module files, two new Warn() member function templates were added to
SemanticsContext and other contextual frameworks. Warn() can't be used
before source locations can be mapped to scopes, but the bulk of
existing code blocks testing ShouldWarn() and FindModuleFile() before
calling Say() were convertible into calls to Warn(). The ones that were
not convertible were extended with explicit calls to
Message::set_languageFeature() and set_usageWarning().
A bare ALLOCATE statement with no SOURCE= rightly earns a warning about
an undefined function result, if that result is an allocatable that
appears in the ALLOCATE. But in the case of a pointer, where the warning
should care more about the pointer's association status than the value
of its target, a bare ALLOCATE should suffice to silence the warning.
FindPolymorphicAllocatableUltimateComponent needs to be
FindPolymorphicAllocatablePotentialComponent. The current search is
missing cases where a derived type has an allocatable component whose
type has a polymorphic allocatable component.
When the result of a function never appears in a variable definition
context, emit a warning.
If the function has multiple result variables due to alternate ENTRY
statements, any definition will suffice.
The implementation of this check is tied to the general variable
definability checking utility in semantics. Every variable definition
context uses it to ensure that no undefinable variable is being defined.
A set of defined variables is maintained in the SemanticsContext and,
when the warning is enabled and no fatal error has been reported, the
scope tree is traversed and all the function subprograms' results are
tested for membership in that set.
Fix what seems to be a regression in semantics in definability checking:
the construct entities of ASSOCIATE and SELECT TYPE constructs are never
pointers or allocatables, even when their selectors are so. SELECT RANK
construct entities, however, can be pointers or allocatables.
f18 current emits an error when an assignment is made to an array
section with a vector subscript, and the array is finalized with a
non-elemental final subroutine. Some other compilers emit this error
because (I think) they want variables to only be finalized in place, not
by a subroutine call involving copy-in & copy-out of the finalized
elements.
Since many other Fortran compilers can handle this case, and there's
nothing in the standards to preclude it, let's downgrade this error
message to a portability warning.
This patch got complicated because the API for the WhyNotDefinable()
utility routine was such that it would return a message only in error
cases, and there was no provision for returning non-fatal messages. It
now returns either nothing, a fatal message, or a non-fatal warning
message, and all of its call sites have been modified to cope.
The utility function GetRelevantObject() seems to be just wrong for
definability checks for the "base object" of a designator, and that's
all for which it is (now?) used. This leads to some false error messages
in Whizard when data-refs with multiple pointer components are defined.
Simplify, and add more test cases.
An INTENT(IN) attribute on a pointer dummy argument prevents
modification of the pointer itself only, not modification of any
component of its target. Fix this case without breaking definability
checking for pointer components of non-pointer INTENT(IN) dummy
arguments.
I explicitly skipped definability checking for construct entities under
a RANK() clause. I don't know what I was thinking at the time; it's
obviously incorrect! Fix, and add tests.
Unlike other executable constructs with associating selectors, the
selector of a SELECT RANK construct can have the ALLOCATABLE or POINTER
attribute, and will work as an allocatable or object pointer within
each rank case, so long as there is no RANK(*) case.
Getting this right exposed a correctness risk with the popular
predicate IsAllocatableOrPointer() -- it will be true for procedure
pointers as well as object pointers, and in many contexts, a procedure
pointer should not be acceptable. So this patch adds the new predicate
IsAllocatableOrObjectPointer(), and updates some call sites of the original
function to use the new one.
Differential Revision: https://reviews.llvm.org/D159043
When the left-hand side of an assignment, or any other context demanding
definability, comprises a designator with a vector subscript that is
known at compilation time to have one or more duplicated elements,
emit an error message.
Differential Revision: https://reviews.llvm.org/D155492
Many semantic checks for constraints related to PURE subprograms
can be implemented in terms of Semantics' "definable.h" utilities,
slightly expanded. Replace some particular PURE constraint
checks with calls to WhyNotDefinable(), except for cases that
had better specific error messages, and start checking some
missing constraints with DEALLOCATE statements and local
variable declarations.
Differential Revision: https://reviews.llvm.org/D147389
When a parameterized derived type has FINAL subroutines, only
those FINAL subroutines whose dummy argument's type matches the
type parameter values of a particular instantiation are relevant
to that instantiation.
Differential Revision: https://reviews.llvm.org/D145741
A reference to a pointer-valued function is a "variable" in the argot of
the Fortran standard, and can be the left-hand side of an assignment
statement or passed as a definable actual argument -- but it is not a
definable pointer, and cannot be associated with a pointer dummy argument
that is not INTENT(IN).
Differential Revision: https://reviews.llvm.org/D143827
The standard's specification for the ASSOCIATED() intrinsic function
describes its optional second argument (TARGET=) as being required
to be a valid target for a pointer assignment statement in which the
first argument (POINTER=) was the left-hand side. Some Fortran compilers
apparently interpret this text as a requirement that the POINTER= argument
actually be a valid left-hand side to a pointer assignment statement,
and emit an error if it is not so. This particularly affects the
use of an explicit NULL pointer as the first argument.
Such usage is well-defined, benign, useful, and supported by at least
two other compilers, so we should continue to accept it. This patch
adds a portability warning and some documentation.
In order to implement the portability warning in the best way, the
special checks on calls to the ASSOCIATED() intrinsic function have
been moved from intrinsic processing to Semantics/check-calls.cpp,
whence they have access to semantics' toolchest. Special checks for
other intrinsic functions might also migrate in the future in order
to keep them all in one place.
Differential Revision: https://reviews.llvm.org/D142768
The pointers and allocatables that appear in ALLOCATE and DEALLOCATE
statements need to be subject to the general definability checks so
that problems with e.g. PROTECTED objects can be caught.
(Also: regularize the capitalization of the DEALLOCATE error messages
while I'm in here so that they're consistent with the messages that
can come out for ALLOCATE.)
Differential Revision: https://reviews.llvm.org/D140149
When a defined object is an array with a vector subscript, and it has a
finalizable type, it may have a final subroutine with a matching or
assumed rank dummy argument that cannot be called. Unless there is
also a suitable elemental final subroutine, diagnose such a case
with an error message.
Differential Revision: https://reviews.llvm.org/D140131
Definability checking is unconditionally flagging the use of a polymorphic
variable as an actual argument for a procedure reference in a PURE subprogram
unless the corresponding dummy is INTENT(IN). This isn't necessary, since
an INTENT(OUT) polymorphic dummy is already caught as an error in the definition
of the callee, which must also be PURE; and an INTENT(IN OUT) or intent-free
dummy is allowed to be passed a polymorphic actual in a PURE context, with
any attempt to deallocate it being caught in the callee.
So add a flag to the definability checker to disable the "polymorphic
definition in PURE context" check when using it to check actual arguments.
Differential Revision: https://reviews.llvm.org/D139044
The infrastructure in semantics that is used to check that the
left-hand sides of normal assignment statements are really definable
variables was not being used to check whether the LHSs of pointer assignments
are modifiable, and so most cases of unmodifiable pointers are left
undiagnosed. Rework the semantics checking for pointer assignments,
NULLIFY statements, pointer dummy arguments, &c. so that cases of
unmodifiable pointers are properly caught. This has been done
by extracting all the various definability checking code that has
been implemented for different contexts in Fortran into one new
facility.
The new consolidated definability checking code returns messages
meant to be attached as "because: " explanations to context-dependent
errors like "left-hand side of assignment is not definable".
These new error message texts and their attached explanations
affect many existing tests, which have been updated. The testing
infrastructure was extended by another patch to properly compare
warnings and explanatory messages, which had been ignored until
recently.
Differential Revision: https://reviews.llvm.org/D136979