A recent fix beefed up semantics checking to catch the case of a call
to an external assumed-length character function; this check has false
positives in the case of an assumed-length character function that is
a dummy procedure. These do have a length that is passed in extra
compiler-created arguments. This patch refines the check and undoes some
changes to tests.
Differential Revision: https://reviews.llvm.org/D126390
This is a support for " #pragma omp atomic compare fail ". It has Parser & AST support for now.
Reviewed By: tianshilei1992
Differential Revision: https://reviews.llvm.org/D123235
The derived type information table construction code had a
crash whose root cause was replacing an expression with one
of its operands -- the deletion of the LHS of that assignment
led to the RHS being invalidated before it could be read.
Fix by cloning the RHS. Also update a TODO message to the
new "_todo_en_US" message class and add a comment about how
it should be resolved.
Differential Revision: https://reviews.llvm.org/D126154
The scalar-default-character-expression that defines the interoperable
name of a function or subroutine (or interface) must have its names
resolved within the context of the subprogram, despite its appearance
on a function-stmt or a subroutine-stmt. Failure to do so can lead
to bogus errors or to incorrect results.
The solution is to defer name resolution for function-stmt suffixes
(but not entry-stmt suffixes) and for subroutine-stmt language binding
specifications to EndSubprogram(). (Their resolution only need to be
deferred to the end of the specification part, but it's cleanest to
deal with it in EndSubprogram().)
Differential Revision: https://reviews.llvm.org/D126153
User-defined derived type I/O subroutines need to be unique for
a given type and operation in any scope, but it is acceptable
to have more than one defined I/O subroutine so long as only one
of them is visible.
Differential Revision: https://reviews.llvm.org/D126152
A utility predicate in semantics was incorrectly determining that
an INTERFACE ASSIGNMENT(=) (or other form of generic) could not have
a specific procedure with an unlimited polymorphic second argument.
This led to a crash later in expression analysis. Fix, and
extend tests.
Differential Revision: https://reviews.llvm.org/D126151
The purity or impurity of a call to a generic interface
depends on the attributes of the specific procedure or specific
binding. Change expression analysis of calls to generic interfaces
to replace the symbol in the parse tree with the specific procedure
or binding; this ensures that later checking for purity in
DO CONCURRENT and other contexts will be accurate.
Remove an "XFAIL" from a test that now passes again with this fix.
Differential Revision: https://reviews.llvm.org/D126150
Name resolution for subprograms checks whether the name is already
present in the enclosing scope as a generic interface, so that the
case of a generic with the same name as one of its specifics can be
handled. The particular means by which the enclosing scope is searched
for the name would resolve the name (bind a symbol to it) as a side
effect. This turns out to be the wrong thing to do when the subprogram
is going to have its symbol created in another scope to cope with its
BIND(C,NAME="name") name, and its Fortran name is already present in the
enclosing scope for a subprogram of the same name but without
BIND(C,NAME="name").
A very long explanation for a one-line fix, sorry. In short, change
the code to look up the name but not resolve it at that point.
Differential Revision: https://reviews.llvm.org/D126149
Semantics was allowing calls to CHARACTER(*) functions, which are odd
things -- they can be declared, and passed around, but can never actually
be called as such. They must be redeclared with an explicit length that
ends up being passed as a hidden argument. So check for these calls
and diagnose them, add tests, and clean up some existing tests that
were in error and now get caught.
Possible TODO for lowering: there were some test cases that used
bad calls to assumed-length CHARACTER*(*) functions and validated
their implementations. I've removed some, and adjusted another,
but the code that somehow implemented these calls may need to be
removed and replaced with an assert about bad semantics.
Differential Revision: https://reviews.llvm.org/D126148
The code in semantics that reinitializes symbol table pointers in
the parse tree of a parameterized derived type prior to a new
instantiation of the type was processing the symbols of the
derived type instantiation scope in arbitrary address order,
which could fail if a reference to a type parameter inherited from
an ancestor type was processed prior to the parent component sequence.
Fix by instantiating components of PDT instantiations in declaration
order.
Differential Revision: https://reviews.llvm.org/D126147
When a Hollerith (or short character) literal is presented as an actual
argument that corresponds to a dummy argument for which a BOZ literal
would be acceptable, treat the Hollerith as if it had been a BOZ
literal in the same way -- and with the same code -- as f18 already
does for the similar extension in DATA statements.
Differential Revision: https://reviews.llvm.org/D126144
Forward references to ENTRY names to pass them as actual procedure arguments
don't work in all cases, exposing some basic ordering problems in
name resolution for these symbols. Refactor; create all the
necessary procedure symbols, and either function result or host association
symbols (for subroutines), at the time that the subprogrma scope is
created, so that the names exist in the scope as text "before"
the ENTRY is processed in name resolution. Some processing
remains in PostEntryStmt() so that we can check that an ENTRY with
an explicit distinct RESULT doesn't also have declarations for the
ENTRY name.
Differential Revision: https://reviews.llvm.org/D126142
The binding names of inner procedures with BIND(C) are not exposed
to the loader and should be ignored for potential conflict errors.
Differential Revision: https://reviews.llvm.org/D126141
Intrinsic module names are not in the user's namespace, so they
are free to declare global names that conflict with intrinsic
modules.
Differential Revision: https://reviews.llvm.org/D126140
As Fortran 2018 15.8.1(3), in a reference to an elemental procedure, if
any argument is an array, each actual argument that corresponds to an
INTENT (OUT) or INTENT (INOUT) dummy argument shall be an array. Add
this semantic check.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D125685
Complex component references (z%RE, z%IM) of complex named constants
should be evaluated at compilation time.
Differential Revision: https://reviews.llvm.org/D125341
Fortran 2018 requires that a compiler allow objects whose rank + corank
is 15, and that's our maximum; detect and diagnose violations.
Differential Revision: https://reviews.llvm.org/D125153
In a function, ENTRY E without an explicit RESULT() creates a
function result entity also named E that is storage associated with
the enclosing function's result. f18 was emitting an incorrect error
message if that function result E was referenced without any
declaration prior to its ENTRY statement when it should have been
implicitly declared instead.
Differential Revision: https://reviews.llvm.org/D125144
As is already supported for dummy procedures, we need to also accept
declarations of procedure pointers that consist of a POINTER attribute
statement followed by an INTERFACE block. (The case of an INTERFACE
block followed by a POINTER statement already works.)
While cleaning this case up, adjust the utility predicate IsProcedurePointer()
to recognize it (namely a SubprogramDetails symbol with Attr::POINTER)
and delete IsProcName(). Extend tests, and add better comments to
symbol.h to document the two ways in which procedure pointers are
represented.
Differential Revision: https://reviews.llvm.org/D125139
The semantic test for an intrinsic assignment to a polymorphic
derived type entity from a type that is an extension of its base
type was reversed, so it would allow assignments that it shouldn't
and disallowed some that it should; and the test case for it
incorectly assumed that the invalid semantics were correct.
Fix the code and the test, and add a new test for the invalid
case (LHS type is an extension of the RHS type).
Differential Revision: https://reviews.llvm.org/D125135
DATA statements in inner procedures were not treating undeclared objects
as implicitly declared variables if the DATA statement appeared in a
specification part; they were treated as host-associated symbols instead.
This was incorrect. Fix DATA statement name resolution to always treat
DATA as if it had appeared in the executable part.
Differential Revision: https://reviews.llvm.org/D125129
A disassociated procedure pointer is allowed to be passed as an absent
actual argument that corresponds to an optional dummy procedure,
but not NULL(); accept that case as well.
Differential Revision: https://reviews.llvm.org/D125127
Actual arguments whose lengths are less than the expected length
of their corresponding dummy argument are errors; but this needs
to be refined. Short actual arguments that are variables remain
errors, but those that are expressions can be (again) extended on
the right with blanks.
Differential Revision: https://reviews.llvm.org/D125115
When processing an entry-stmt in name resolution, attrs_ was
reset before SetBindNameOn was called, causing the symbol to lose
the binding label information.
Differential Revision: https://reviews.llvm.org/D125097
As Fortran 2018 5.2.2 states, a program shall consist of exactly one
main program. Add this semantic check.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D125186
The code below causes flang to crash with an exception.
After fixing the crash flang with an internal error "no symbol found for 'bar'"
This change fixes all the issues.
program name
implicit none
integer, parameter :: bar = 1
integer foo(bar) /bar*2/
end program name
Reviewed By: kiranchandramohan, klausler
Differential Revision: https://reviews.llvm.org/D124914
As Fortran 2018 states, in each where-assignment-stmt, the mask-expr and
the variable being defined shall be arrays of the same shape. The
previous check does not consider checking if it is an array.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D125022
When we pass an alternate return specifier to a regular (not an asterisk)
dummy argument, flang would throw an internal compiler error of
derefencing a null pointer.
To avoid the ICE, a check was added.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D123947
The RETURN statement is allowed in functions and subroutines, but not
in main programs. It is however a common extension, which we also
implement, to allow RETURN from main programs -- we only issue a
portability warning when -pedantic or -std=f2018 are set.
This patch fixes false positives for this portability warning, where it
was triggered also when RETURN was present in functions or subroutines.
Fixexs #55080
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D124732
As Fortran 2018 C1533, a nonintrinsic elemental procedure shall not be
used as an actual argument. The semantic check for implicit iterface is
missed.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D124379
Semantics is not preventing a named common block to appear with
different size in a same file (named common block should always have
the same storage size (see Fortran 2018 8.10.2.5), but it is a common
extension to accept different sizes).
Lowering was not coping with this well, since it just use the first
common block appearance, starting with BLOCK DATAs to define common
blocks (this also was an issue with the blank common block, which can
legally appear with different size in different scoping units).
Semantics is also not preventing named common from being initialized
outside of a BLOCK DATA, and lowering was dealing badly with this,
since it only gave an initial value to common blocks Globals if the
first common block appearance, starting with BLOCK DATAs had an initial
value.
Semantics is also allowing blank common to be initialized, while
lowering was assuming this would never happen, and was never creating
an initial value for it.
Lastly, semantics was not complaining if a COMMON block was initialized
in several scoping unit in a same file, while lowering can only generate
one of these initial value.
To fix this, add a structure to keep track of COMMON block properties
(biggest size, and initial value if any) at the Program level. Once the
size of a common block appearance is know, the common block appearance
is checked against this information. It allows semantics to emit an error
in case of multiple initialization in different scopes of a same common
block, and to warn in case named common blocks appears with different
sizes. Lastly, this allows lowering to use the Program level info about
common blocks to emit the right GlobalOp for a Common Block, regardless
of the COMMON Block appearances order: It emits a GlobalOp with the
biggest size, whose lowest bytes are initialized with the initial value
if any is given in a scope where the common block appears.
Lowering is updated to go emit the common blocks before anything else so
that the related GlobalOps are available when lowering the scopes where
common block appear. It is also updated to not assume that blank common
are never initialized.
Differential Revision: https://reviews.llvm.org/D124622
A non-CHARACTER expression in a CASE statement is allowed to have
a distinct kind (not type) from the expression in its SELECT CASE.
If a value in a CASE statement is out of range for the SELECT CASE
type, emit a warning, but it should not be a fatal error.
Differential Revision: https://reviews.llvm.org/D124544
Name resolution fails with a bogus "is not a variable" error message
when a host-associated object appears in a NAMELIST group. The root
cause is that ConvertToObjectEntity() returns false for host-associated
objects. Fix that, and also apply a similar fix to ConvertToProcEntity()
nearby.
Differential Revision: https://reviews.llvm.org/D124541
Semantics now needs to preserve the parse trees from module files,
in case they contain parameterized derived type definitions with
component initializers that may require re-analysis during PDT
instantiation. Save them in the SemanticsContext.
Differential Revision: https://reviews.llvm.org/D124467
At the top level of program units in a source file, two subprograms
are allowed to have the same name if at least one of them has a
distinct interoperable binding name. F18's symbol table requires
(most) symbols in a scope to have distinct names, though. Solve
by using compiler-created names for the symbols of global scope
subprograms that have interoperable binding names.
Differential Revision: https://reviews.llvm.org/D124295
F(X)=Y may be initially parsed as a statement function definition; an
existing pass will detect statement functions that should be rewritten
into assignment statemets with array element references as their
left-hand side variables. However, F() may also be a reference to a
function that returns a data pointer, and f18 did not handle this
case correctly.
The right fix is to rewrite the parse tree for F(X)=Y into an assignment
to a function reference result. The cases that are actually assignments
to array elements -- including all of the cases previously handled --
will have their left-hand sides converted to array element references
later by another existing rewriting step.
Differential Revision: https://reviews.llvm.org/D124299
A recent change that corrected the name resolution of a generic interface
when the same name was visible in scope incorrectly prevented a local
generic from shadowing an outer name that is not a generic, subprogram,
or derived type -- e.g., a simple variable -- leading to an inappropriate
error message.
Differential Revision: https://reviews.llvm.org/D124276
The following code causes the compiler to ICE in several places due to
lack of support of recursive procedure definitions through the function
result.
function foo() result(r)
procedure(foo), pointer :: r
end function foo
A missing "!" in the call interface lowering caused all derived type
arguments without length parameters that require and explicit interface
to be passed via fir.box (runtime descriptor).
This was not the intent: there is no point passing a simple derived type
scalars or explicit shapes by descriptor just because they have an attribute
like TARGET. This would actually be problematic with existing code that is
not always 100% compliant: some code implicitly calls procedures with
TARGET dummy attributes (this is not something a compiler can enforce
if the call and procedure definition are not in the same file).
Add a Scope::IsDerivedTypeWithLengthParameter to avoid passing derived
types with only kind parameters by descriptor. There is no point, the
callee knows about the kind parameter values.
Differential Revision: https://reviews.llvm.org/D123990
When resolving a procedure reference, do not allow a successful
intrinsic procedure probe result to override an existing
symbol.
Differential Revision: https://reviews.llvm.org/D123905
Adds flang/include/flang/Common/log2-visit.h, which defines
a Fortran::common::visit() template function that is a drop-in
replacement for std::visit(). Modifies most use sites in
the front-end and runtime to use common::visit().
The C++ standard mandates that std::visit() have O(1) execution
time, which forces implementations to build dispatch tables.
This new common::visit() is O(log2 N) in the number of alternatives
in a variant<>, but that N tends to be small and so this change
produces a fairly significant improvement in compiler build
memory requirements, a 5-10% improvement in compiler build time,
and a small improvement in compiler execution time.
Building with -DFLANG_USE_STD_VISIT causes common::visit()
to be an alias for std::visit().
Calls to common::visit() with multiple variant arguments
are referred to std::visit(), pending further work.
This change is enabled only for GCC builds with GCC >= 9;
an earlier attempt (D122441) ran into bugs in some versions of
clang and was reverted rather than simply disabled; and it is
not well tested with MSVC. In non-GCC and older GCC builds,
common::visit() is simply an alias for std::visit().
The x%KIND inquiry needs to be supported when 'x' is itself
a complex part reference or a type parameter inquiry.
Differential Revision: https://reviews.llvm.org/D123733
A POINTER attribute statement is allowed to add the POINTER attribute
to a procedure entity that has already been declared, e.g. with an
INTERFACE block.
Differential Revision: https://reviews.llvm.org/D123732
f18 was emitting a warning about short character actual arguments to
subprograms and statement functions; every other compiler considers this
case to be an error.
Differential Revision: https://reviews.llvm.org/D123731
For parameterized derived type component initializers whose
expressions' types depend on parameter values, f18's current
scheme of analyzing the initialization expression once during
name resolution fails. For example,
type :: pdt(k)
integer, kind :: k
real :: component = real(0.0, kind=k)
end type
To handle such cases, it is necessary to re-analyze the parse
trees of these initialization expressions once for each distinct
initialization of the type.
This patch adds code to wipe an expression parse tree of its
typed expressions, and update those of its symbol table pointers
that reference type parameters, and then re-analyze that parse
tree to generate the properly typed component initializers.
Differential Revision: https://reviews.llvm.org/D123728
Prior to this patch, the semantics utility GetExpr() will crash
unconditionally if it encounters a typed expression in the parse
tree that has not been set by expression semantics. This is the
right behavior when called from lowering, by which time it is known
that the program had no fatal user errors, since it signifies a
fatal internal error. However, prior to lowering, in the statement
semantics checking code, a more nuanced test should be used before
crashing -- specifically, we should not crash in the face of a
missing typed expression when in error recovery mode.
Getting this right requires GetExpr() and its helper class to have
access to the semantics context, so that it can check AnyFatalErrors()
before crashing. So this patch touches nearly all of its call sites.
Differential Revision: https://reviews.llvm.org/D123873