When writing tests for a previous problem, I ran across situations where the
compiler was failing calls to CHECK(). In these situations, the compiler had
inconsistent semantic information because the programs were erroneous. This
inconsistent information was causing the calls to CHECK().
I fixed this by avoiding the code that ended up making the failed calls to
CHECK() and making sure that we were only avoiding these situations when the
associated symbols were erroneous.
I also added tests that would cause the calls to CHECK() without these changes.
Differential Revision: https://reviews.llvm.org/D99342
Binding labels start as expressions but they have to evaluate to
constant character of default kind, so they can be represented as an
std::string. Leading and trailing blanks have to be removed, so the
folded expression isn't exactly right anyway.
So all BIND(C) symbols now have a string binding label, either the
default or user-supplied one. This is recorded in the .mod file.
Add WithBindName mix-in for details classes that can have a binding
label so that they are all consistent. Add GetBindName() and
SetBindName() member functions to Symbol.
Add tests that verifies that leading and trailing blanks are ignored
in binding labels and that the default label is folded to lower case.
Differential Revision: https://reviews.llvm.org/D99208
Binding labels start as expressions but they have to evaluate to
constant character of default kind, so they can be represented as an
std::string. Leading and trailing blanks have to be removed, so the
folded expression isn't exactly right anyway.
So all BIND(C) symbols now have a string binding label, either the
default or user-supplied one. This is recorded in the .mod file.
Add WithBindName mix-in for details classes that can have a binding
label so that they are all consistent. Add GetBindName() and
SetBindName() member functions to Symbol.
Add tests that verifies that leading and trailing blanks are ignored
in binding labels and that the default label is folded to lower case.
Differential Revision: https://reviews.llvm.org/D99208
When writing tests for a previous problem, I ran across situations where we
were not producing error messages for declarations of specific procedures of
generic interfaces where every other compiler I tested (except nvfotran) did.
I added a check to CheckExtantExternal() and renamed it since it now checks for
erroneous extant symbols generally.
I also removed a call to this function from processing for ENTRY statements,
since it seemed unnecessary and its presence caused bogus error messages.
I also added some tests for erroneous declarations where we were not producing
error messages.
Differential Revision: https://reviews.llvm.org/D99111
If you specify a specific procedure of a generic interface that has the same
name as both the generic interface and a preceding derived type, the compiler
would fail an internal call to CHECK(). I fixed this by testing for this
situation when processing specific procedures. I also added a test that will
cause the call to CHECK() to fail without this new code.
Differential Revision: https://reviews.llvm.org/D99085
This patch fixes a bug to allow ordered construct within a non-worksharing loop, also adds more sema checks.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D98733
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
Adds support for `-fget-symbols-sources` in the new Flang driver. All
relevant tests are updated to use the new driver when
`FLANG_BUILD_NEW_DRIVER` is set.
`RUN` lines in tests are updated so `-fsyntax-only`
comes before `-fget-symbols-sources`. That's because:
* both `-fsyntax-only` and `-fget-symbols-sources` are
action flags, and
* the new driver, flang-new, will only consider the right-most
action flag.
In other words, this change is needed so that the tests work with both
`f18` (requires both flags) and `flang-new` (only considers the last
action flag).
Differential Revision: https://reviews.llvm.org/D98191
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
If you specify a type-bound procedure with an alternate return, there
will be no symbol associated with that dummy argument. In such cases,
the compiler's list of dummy arguments will contain a nullptr. In our
analysis of the PASS arguments of type-bound procedures, we were
assuming that all dummy arguments had non-null symbols associated with
them and were using that assumption to get the name of the dummy
argument. This caused the compiler to try to dereference a nullptr.
I fixed this by explicitly checking for a nullptr and, in such cases, emitting
an error message. I also added tests that contain type-bound procedures with
alternate returns in both legal and illegal constructs to ensure that semantic
analysis is working for them.
Differential Revision: https://reviews.llvm.org/D98430
You can define a base type with a type-bound procedure which is erroneously
missing a NOPASS attribute and then define another type that extends the base
type and overrides the erroneous procedure. In this case, when we perform
semantic checking on the overriding procedure, we verify the "pass index" of
the overriding procedure. The attempt to get the procedure's pass index fails
a call to CHECK().
I fixed this by calling SetError() on the symbol of the overridden procedure in
the base type. Then, I check HasError() before executing the code that invokes
the failing call to CHECK(). I also added a test that will cause the compiler
to fail the call to CHECK() without this change.
Differential Revision: https://reviews.llvm.org/D98355
We have a "<" operator defined on the type semantics::Symbol that's based on
the symbols' locations in the cooked character stream. This is potentially
problematic when comparing symbols from .mod files when the cooked character
streams themselves might be allocated to varying memory locations.
This change fixes that by using the order in which symbols are created as the
basis for the "<" operator. Thanks to Tim and Peter for consultation on the
necessity of doing this and the idea for what to use as the basis of the sort.
This change in the "<" operator changed the expected results for three of the
tests. I manually inspected the new results, and they look OK to me. The
differences in data05.f90 and typeinfo01.f90 are entirely the order, offsets,
and sizes of the derived type components. The changes in resolve102.f90 are
due to the new, different "<" operator used for sorting.
Differential Revision: https://reviews.llvm.org/D98225
When we have a subprogram that has been determined to contain errors, we do not
perform name resolution on its execution part. In this case, if the subprogram
contains a NULLIFY statement, the parser::Name of a pointer object in a NULLIFY
statement will not have had name resolution performed on it. Thus, its symbol
will not have been set. Later, however, we do semantic checking on the NULLIFY
statement. The code that did this assumed that the parser::Name of the
pointer object was non-null.
I fixed this by just removing the null pointer check for the "symbol" member of
the "parser::Name" of the pointer object when doing semantic checking for
NULLIFY statements. I also added a test that will make the compiler crash
without this change.
Differential Revision: https://reviews.llvm.org/D98184
We were allowing procedures with the MODULE prefix to be declared at the global
scope. This is prohibited by C1547 and was causing an internal check of the
compiler to fail.
I fixed this by adding a check. I also added a test that would trigger a crash
without this change.
Differential Revision: https://reviews.llvm.org/D97875
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
Semantic checks for the following OpenMP 4.5 clauses.
1. 2.15.4.2 - Copyprivate clause
2. 2.15.3.4 - Firstprivate clause
3. 2.15.3.5 - Lastprivate clause
Add related test cases and resolve test cases marked as XFAIL.
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D91920
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
Most Fortran compilers accept the following benign extension,
and it appears in some applications:
SUBROUTINE FOO(A,N)
IMPLICIT NONE
REAL A(N) ! N is used before being typed
INTEGER N
END
Allow it in f18 only for default integer scalar dummy arguments.
Differential Revesion: https://reviews.llvm.org/D96982
Add the following options:
* -fdebug-dump-symbols
* -fdebug-dump-parse-tree
* -fdebug-dump-provenance
Summary of changes:
- Add 3 new frontend actions: DebugDumpSymbolsAction, DebugDumpParseTreeAction and DebugDumpProvenanceAction
- Add a unique pointer to the Semantics instance created in PrescanAndSemaAction
- Move fatal semantic error reporting to its own method, FrontendActions#reportFatalSemanticErrors
- Port most tests using `-fdebug-dump-symbols` and `-fdebug-dump-parse-tree` to the new driver if built, otherwise default to f18
Differential Revision: https://reviews.llvm.org/D96716
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
The intrinsic procedure table properly classify the various
intrinsics, but the PURE and ELEMENTAL attributes that these
classifications imply don't always make it to the utility
predicates that test symbols for them, leading to spurious
error messages in some contexts. So set those attribute flags
as appropriate in name resolution, using a new function to
isolate the tests.
An alternate solution, in which the predicates would query
the intrinsic procedure table for these attributes on demand,
was something I also tried, so that this information could
come directly from an authoritative source; but it would have
required references to the intrinsic table to be passed along
on too many seemingly unrelated APIs and ended up looking messy.
Several symbol table tests needed to have their expected outputs
augmented with the PURE and ELEMENTAL flags. Some bogus messages
that were flagged as such in test/Semantics/doconcurrent01.f90 were
removed, since they are now correctly not emitted.
Differential Revision: https://reviews.llvm.org/D96878
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
Add the following options:
* -fimplicit-none and -fno-implicit-none
* -fbackslash and -fno-backslash
* -flogical-abbreviations and -fno-logical-abbreviations
* -fxor-operator and -fno-xor-operator
* -falternative-parameter-statement
* -finput-charset=<value>
Summary of changes:
- Enable extensions in CompilerInvocation#ParseFrontendArgs
- Add encoding_ to Fortran::frontend::FrontendOptions
- Add encoding to Fortran::parser::Options
Differential Revision: https://reviews.llvm.org/D96407
This patch adds the following compiler frontend driver options:
* -fdebug-unparse (f18 spelling: -funparse)
* -fdebug-unparse-with-symbols (f18 spelling: -funparse-with-symbols)
The new driver will only accept the new spelling. `f18` will accept both
the original and the new spelling.
A new base class for frontend actions is added: `PrescanAndSemaAction`.
This is added to reduce code duplication that otherwise these new
options would lead to. Implementation from
* `ParseSyntaxOnlyAction::ExecutionAction`
is moved to:
* `PrescanAndSemaAction::BeginSourceFileAction`
This implementation is now shared between:
* PrescanAndSemaAction
* ParseSyntaxOnlyAction
* DebugUnparseAction
* DebugUnparseWithSymbolsAction
All tests that don't require other yet unimplemented options are
updated. This way `flang-new -fc1` is used instead of `f18` when
`FLANG_BUILD_NEW_DRIVER` is set to `On`. In order to facilitate this,
`%flang_fc1` is added in the LIT configuration (lit.cfg.py).
`asFortran` from f18.cpp is duplicated as `getBasicAsFortran` in
FrontendOptions.cpp. At this stage it's hard to find a good place to
share this method. I suggest that we revisit this once a switch from
`f18` to `flang-new` is complete.
Differential Revision: https://reviews.llvm.org/D96483
The following _action_ options are always used with `-fsyntax-only`
(also an _action_ option):
* -fdebug-dump-symbols
* -fdebug-dump-parse-tree
This patch makes the above options imply `-fsyntax-only`.
From the perspective of `f18` this change saves typing and is otherwise
a non-functional change. But it will simplify things in the new driver,
`flang-new`, in which only the last action option is taken into account
and executed. In other words, the following would only run
`-fsyntax-only`:
```
flang-new -fdebug-dump-symbols -fsyntax-only <input>
```
whereas this would only run `-fdebug-dump-symbols`:
```
flang-new -fsyntax-only -fdebug-dump-symbols <input>
```
Differential Revision: https://reviews.llvm.org/D96528
Implementation of Do loop iteration variable check, Do while loop check, Do loop cycle restrictions.
Also to check whether the ordered clause is present on the loop construct if any ordered region ever
binds to a loop region arising from the loop construct.
Files:
check-omp-structure.h
check-omp-structure.cpp
resolve-directives.cpp
Testcases:
omp-do06-positivecases.f90
omp-do06.f90
omp-do08.f90
omp-do09.f90
omp-do10.f90
omp-do11.f90
omp-do12.f90
omp-do13.f90
omp-do14.f90
omp-do15.f90
omp-do16.f90
omp-do17.f90
Reviewed by: Kiran Chandramohan @kiranchandramohan , Valentin Clement @clementval
Differential Revision: https://reviews.llvm.org/D92732
Instead of using a message attachment with further details,
emit the details as part of a single message.
Differential Revision: https://reviews.llvm.org/D96465
Some state in name resolution is stored in the DeclarationVisitor
instance and processed at the end of the specification part.
This state needs to accommodate nested specification parts, namely
the ones that can be nested in a subroutine or function interface
body.
Differential Revision: https://reviews.llvm.org/D96466
Add support for the following options:
* -fopenmp
* -fopenacc
Update OpenMP and OpenACC semantics tests to use the new driver if it is built, otherwise use f18.
OpenMP tests that include `use omp_lib` or run `test_symbols.sh` have not been updated as they require options `-intrinsic-module-directory` and `-funparse-with-symbols` which are currently not implemented in the new driver.
Similarly OpenACC tests that run `test_symbols.sh` have not been updated.
This patch also moves semanticsContext to CompilerInvocation and creates it in CompilerInvocation#setSemanticsOpts so that the semantics context can use Fortran::parser::Options#features.
Summary of changes:
- Move semanticsContext to CompilerInvocation.h
- Update OpenMP and OpenACC semantics tests that do not rely on `-intrinsic-module-directory` and `-funparse-with-symbols` to use %flang
Differential Revision: https://reviews.llvm.org/D96032
Now that semantics is working, the standard -fsyntax-only option of
GNU and Clang should be used as the name of the option that causes
f18 to just run the front-end. Support both options in f18, silently
accepting the old option as a synonym for the new one (as
preferred by the code owner), and replace all instances of the
old -fparse-only option with -fsyntax-only throughout the source base.
Differential Revision: https://reviews.llvm.org/D95887
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
kernels loop and enter data had a too restrictive constraint for the wait clause.
The wait clause is allowed multiple times and not only once. This patch fix this problem.
Reviewed By: SouraVX
Differential Revision: https://reviews.llvm.org/D95469
Restriction on clauses for the EXIT DATA directive were not fully correct.
This patch fixes the situation. The async, if and finalize clauses are allowed
only once.
Reviewed By: SouraVX
Differential Revision: https://reviews.llvm.org/D95470
Restriction on clauses for the HOST_DATA directive were not fully correct.
This patch fixes the situation. The if and if_present clauses are allowed
only once.
Reviewed By: SouraVX
Differential Revision: https://reviews.llvm.org/D95473
Split the tests from acc-clause-validity.f90 in dedicated files by directives.
The file acc-clause-validity.f90 was getting too big to be correctly maintained.
Tests are identical.
Reviewed By: SouraVX
Differential Revision: https://reviews.llvm.org/D95328
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