35 Commits

Author SHA1 Message Date
Peter Klausler
442ae603c5
[flang] Warn about inexact real literal implicit widening pitfall (#152799)
When a REAL or COMPLEX literal appears without an explicit kind suffix
or a kind-determining exponent letter, and the conversion of that
literal from decimal to binary is inexact, emit a warning if that
constant is later implicitly widened to a more precise kind, since it
will have a different value than was probably intended.

Values that convert exactly from decimal to default real, e.g. 1.0 and
0.125, do not elicit this warning.

There are many contexts in which Fortran implicitly converts constants.
This patch covers name constant values, variable and component
initialization, constants in expressions, structure constructor
components, and array constructors.

For example, "real(8) :: tenth = 0.1" is a common Fortran bug that's
hard to find, and is one that often trips up even experienced Fortran
programmers. Unlike C and C++, the literal constant 0.1 is *not* double
precision by default, and it does not have the same value as 0.1d0 or
0.1_8 do when it is converted from decimal to real(4) and then to
real(8).
2025-08-13 14:36:13 -07:00
Peter Klausler
9f8ff4b77d
[flang] Revamp evaluate::CoarrayRef (#136628)
Bring the typed expression representation of a coindexed reference up to
F'2023, which removed some restrictions that had allowed the current
representation to suffice for older revisions of the language. This new
representation is somewhat more simple -- it uses a DataRef as its base,
so any subscripts in a part-ref can be represented as an ArrayRef there.

Update the code that creates the CoarrayRef, and add more checking to
it, as well as actually capturing any STAT=, TEAM=, & TEAM_NUMBER=
specifiers that might appear. Enforce the constraint that the part-ref
must have subscripts if it is an array. (And update a pile of
copied-and-pasted test code that lacked such subscripts.)
2025-05-12 12:02:15 -07:00
Peter Klausler
6df27dd42d
[flang] Fix missed case of symbol renaming in module file generation (#132475)
The map of symbols requiring new local aliases for USE association needs
to use the symbols' ultimate resolutions to avoid missing cases that can
arise in convoluted codes with lots of confusing renamings.

Fixes https://github.com/llvm/llvm-project/issues/132435.
2025-03-26 12:09:38 -07:00
Michael Kruse
b815a3942a
[Flang] Move non-common headers to FortranSupport (#124416)
Move non-common files from FortranCommon to FortranSupport (analogous to
LLVMSupport) such that

* declarations and definitions that are only used by the Flang compiler,
but not by the runtime, are moved to FortranSupport

* declarations and definitions that are used by both ("common"), the
compiler and the runtime, remain in FortranCommon

* generic STL-like/ADT/utility classes and algorithms remain in
FortranCommon

This allows a for cleaner separation between compiler and runtime
components, which are compiled differently. For instance, runtime
sources must not use STL's `<optional>` which causes problems with CUDA
support. Instead, the surrogate header `flang/Common/optional.h` must be
used. This PR fixes this for `fast-int-sel.h`.

Declarations in include/Runtime are also used by both, but are
header-only. `ISO_Fortran_binding_wrapper.h`, a header used by compiler
and runtime, is also moved into FortranCommon.
2025-02-06 15:29:10 +01:00
Peter Klausler
fc97d2e68b
[flang] Add UNSIGNED (#113504)
Implement the UNSIGNED extension type and operations under control of a
language feature flag (-funsigned).

This is nearly identical to the UNSIGNED feature that has been available
in Sun Fortran for years, and now implemented in GNU Fortran for
gfortran 15, and proposed for ISO standardization in J3/24-116.txt.

See the new documentation for details; but in short, this is C's
unsigned type, with guaranteed modular arithmetic for +, -, and *, and
the related transformational intrinsic functions SUM & al.
2024-12-18 07:02:37 -08:00
Youngsuk Kim
d5dd7d230e [flang] Tidy uses of raw_string_ostream (NFC)
As specified in the docs,
1) raw_string_ostream is always unbuffered and
2) the underlying buffer may be used directly

( 65b13610a5226b84889b923bae884ba395ad084d for further reference )

Avoid unneeded calls to raw_string_ostream::str(), to avoid excess indirection.
2024-09-17 12:20:21 -05:00
Peter Klausler
9ce8e63ceb
[flang] Better renaming in module files (#93106)
When a symbol from one module is used in another without an explicit USE
association, the module file output code may need to use another name
for it -- either with a name that is already available via USE
association with renaming, or by means of a new private USE association,
possibly with renaming to avoid a clash.

Module file output was dealing properly with names of derived types, but
wasn't accounting for symbols that appear in expressions other than
initializations. This was specifically a problem with an application
module that had a call to a NOPASS type-bound procedure in an array
bound specification expression, which semantics had resolved to the name
of a private module function.

This patch implements renaming, when necessary, for all symbols
appearing in expressions and type names, and replaces the previous
implementation of derived type renaming. It also gets a little smarter
about avoiding the creation of compiler-generated names when a name from
another module has been brought into scope already by means of USE
association with renaming.
2024-05-23 16:20:51 -07:00
Peter Klausler
22c59e01cd
[flang] Don't crash on bad inherited implied DO type (#91073)
Fortran has an ambiguously defined rule about the typing of index
variables of implied DO loops in DATA statements and array constructors
that omit an explicit type specification. Such indices have the type
that they would have "if they were variables" in the innermost enclosing
scope. Although this could, and perhaps should, be read to mean that
implicit typing rules active in that innermost enclosing scope should be
applied, every other Fortran compiler interprets that language to mean
that if there is a type declaration for that name that is visible from
the enclosing scope, it is applied, and it is an error if that type is
not integer.

Fixes https://github.com/llvm/llvm-project/issues/91053.
2024-05-09 10:17:15 -07:00
Peter Klausler
1bea0347bf
[flang] Fix mod file generation of derived type initializers... (#70511)
... when the derived type used in the structure constructor(s) is from
another module and not use-associated into the current module.

This came up in a test with a derived type component default initializer
of "c_null_ptr", which is replaced with the expression
"__builtin_c_ptr(address=0_8)"; the derived type name "__builtin_c_ptr"
is not available in the current scope, and the module file would fail
semantic analysis when USE'd.

The best solution that I found was to extend module file generation to
detect this case and handle it by inserting the right USE association to
the ultimate derived type symbol, possibly with renaming to a
compiler-created name in the case of a conflict.

To implement this transformation, it was necessary to fix the utility
evaluate::CollectSymbols() to include the derived type symbol from a
structure constructor. This involved extending the expression traversal
framework to visit the derived type spec of a structure constructor.
Extending CollectSymbols() caused a lowering test to fail mysteriously,
so I tracked down the code in PFTBuilder that didn't expect to see a
DerivedTypeDetails symbol and dealt with it there.
2023-10-31 12:17:00 -07:00
jeanPerier
0a10e88915
[flang] Implement legacy %VAL and %REF actual arguments (#70343)
Update evaluate::ActualArgument to propagate the %VAL and %REF markers
until lowering.
Semantic checks are added to %VAL to ensure the argument is a numerical
or logical scalar.

I did not push these markers into the characteristics because other
compilers do not complain about inconsistent usages (e.g. using %VAL in
a call on a procedure with an interface without VALUE dummies is not
flagged by any compilers I tested, and it is not an issue for lowering,
so I decided to stay simple here and minimize the footprint of these
legacy features).

Lowering retrieves these markers and does the right thing: pass %VAL in
registers and pass %REF by address without adding any extra arguments
for characters.
2023-10-27 10:33:57 +02:00
Peter Klausler
c465158e45
[flang] Don't emit debugging output to module file
When a constant array value has a non-default lower bound, the current
expression formatting code uses a non-Fortran syntax to dump the lower
bounds. (There's no way in Fortran to explicitly specify such a constant value,
but they can be created through the use of named constants.)  But we
don't want this lower bounds syntax from expression dumping to show up
in module files, since it can't be parsed back in.  So disable that
part of expression formatting by default.

Fixes https://github.com/llvm/llvm-project/issues/64391.

Differential Revision: https://reviews.llvm.org/D157330
2023-08-08 10:28:00 -07:00
Peter Klausler
16c4b320fe
[flang] Correct handling of non-default lower bounds in ASSOCIATE with named constants
Work through several issues with LBOUND() and UBOUND() of ASSOCIATE
construct entities that have been associated with named constants or
subobjects of named constants that are sporting non-default lower bounds.
Sometimes the non-default lower bounds matter, sometimes they don't.
Add a fairly exhaustive test to work through the possibilities.

Differential Revision: https://reviews.llvm.org/D156756
2023-08-01 09:54:31 -07:00
Peter Klausler
f513bd8088
[flang] CUDA Fortran - part 4/5: definability and characteristics
Extend the definability and procedure characteristics checking
infrastructure in semantics to check for context-dependent CUDA object
definability violations and problems with CUDA attribute incompatibility
in procedure interfaces.

Depends on https://reviews.llvm.org/D150159,
https://reviews.llvm.org/D150161, & https://reviews.llvm.org/D150162.

Differential Revision: https://reviews.llvm.org/D150163
2023-05-31 14:25:38 -07:00
Peter Klausler
036701a177 [flang] Correct procedure pointer (or dummy) compatibility check
Fix a subtle bug in procedure compatibility checking with base
derived types vs. their extensions to ensure that a procedure
expecting an extended type cannot be associated with a pointer
(or dummy procedure) to a procedure expecting a base type.

  subroutine s1(base); ... subroutine s2(extended)
  procedure(s1), pointer :: p
  p => s2 ! <- must be caught as an error

Differential Revision: https://reviews.llvm.org/D142753
2023-01-27 14:53:09 -08:00
Peter Klausler
01688ee9df [flang] Accommodate unknowable CHARACTER length in evaluate::ArrayConstructor<>
The internal representation for array constructors in expressions during semantic
analysis needs to be able to accommodate circumstances (e.g. TRIM(), substrings)
in which the length of the elements in the array is either unknown or cannot be
represented as a context-free integer expression.

Differential Revision: https://reviews.llvm.org/D139041
2022-12-02 10:37:28 -08:00
Peter Klausler
cd03e96f00 [flang] Add & use a better visit() (take 2)
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().
2022-04-16 16:00:48 -07:00
Andrzej Warzynski
4ca111d4cb Revert "[flang] Add & use a better visit()"
This reverts commit 2ab9990c9eb79682a4d4b183dfbc7612d3e55328. It has
caused multiple build failures:
*  https://lab.llvm.org/buildbot/#/builders/177/builds/4346
*  https://lab.llvm.org/buildbot/#/builders/180/builds/3803
*  https://lab.llvm.org/buildbot/#/builders/175/builds/10419
*  https://lab.llvm.org/buildbot/#/builders/191/builds/4318
*  https://lab.llvm.org/buildbot/#/builders/173/builds/4274
*  https://lab.llvm.org/buildbot/#/builders/181/builds/4297

All these bots failed with a time-out:
```
command timed out: 1200 seconds without output running [b'ninja', b'-j', b'32'], attempting to kill
```
I'm guessing that that's due to template instantiations failing at some
point (https://reviews.llvm.org/D122441 introduced a custom
implementation of std::visit). Everything seems fine when either:
* building on X86 with GCC or Clang (tested with GCC 9.3 and Clang 12)
* building on AArch64 with GCC (tested with GCC 11)
2022-03-28 10:46:47 +00:00
Peter Klausler
2ab9990c9e [flang] Add & use a better visit()
Adds flang/include/flang/Common/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.

Differential Revision: https://reviews.llvm.org/D122441
2022-03-25 13:15:20 -07:00
Jean Perier
7f1adbaba9 [flang] Fix LBOUND rewrite on descriptor components
GetLowerBoundHelper rewrite in https://reviews.llvm.org/D121488 was
incorrect with POINTER/ALLOCATABLE components. The rewrite created a
descriptor inquiry to the component symbol only instead of the whole
named entity. The base information was lost, and not retrievable.
LBOUND(a(10)%p) became LBOUND(p).

Fix this regression, and also update DescriptorInquiry unparsing to
carry the kind information. DescriptorInquiries are KIND 8 expressions,
while LBOUND/SIZE/RANK, %LEN are default kind expressions.
This caused `print *,lbound(x,kind=8)` to unparse as `print*,lbound(x)` which is not
semantically the same (this unparsing issue was not an issue for
lowering, but I noticed it while writing my regression test).

Differential Revision: https://reviews.llvm.org/D122406
2022-03-25 09:00:56 +01:00
Peter Klausler
5c5bde1bb6 [flang] Fold SCALE()
Fold references to the intrinsic function SCALE().

(Also work around some MSVC headaches somehow exposed by
this patch: disable a bogus MSVC warning that began to appear
in unrelated source files, and avoid the otherwise-necessary
use of the "template" keyword in a call to a template member
function of a class template.)

Differential Revision: https://reviews.llvm.org/D117150
2022-01-15 09:31:00 -08:00
Peter Klausler
00e0de0572 [flang] Extension: initialization of LOGICAL with INTEGER & vice versa
We already accept assignments of INTEGER to LOGICAL (& vice versa)
as an extension, but not initialization.  Extend initialization
to cover those cases.

(Also fix misspelling in nearby comment as suggested by code reviewer.)

Decouple an inadvertent dependence cycle by moving two
one-line function definitions into a header file.

Differential Revision: https://reviews.llvm.org/D117159
2022-01-13 14:22:45 -08:00
peter klausler
9245f35580 [flang] Validate SIZE(x,DIM=n) dimension for assumed-size array x
Catch invalid attempts to extract the unknowable extent of the last
dimension of an assumed-size array dummy argument, and clean up
problems with assumed-rank arguments in similar circumstances
exposed by testing the fix.

Differential Revision: https://reviews.llvm.org/D109918
2021-09-17 10:14:18 -07:00
peter klausler
e3b2f1b682 [flang] [NFC] Repair build with GCC 7.3
Work around two problems with GCC 7.3.
One is its inability to implement "constexpr operator=(...) = default;"
in a class with a std::optional<> component; another is a legitimate-
looking warning about an unused variable.

Differential Revision: https://reviews.llvm.org/D104731
2021-06-22 13:52:30 -07:00
peter klausler
ac9641753b [flang] Support known constant lengths in DynamicType
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
2021-06-03 14:25:22 -07:00
Peter Steinfeld
52cc9df1c1 [flang] Improve constant folding for type parameter inquiries
We were not folding type parameter inquiries for the form 'var%typeParam'
where 'typeParam' was a KIND or LEN type parameter of a derived type and 'var'
was a designator of the derived type.  I fixed this by adding code to the
function 'FoldOperation()' for 'TypeParamInquiry's to handle this case.  I also
cleaned up the code for the case where there is no designator.

In order to make the error messages correctly refer to both the points of
declaration and instantiation, I needed to add an argument to the function
'InstantiateIntrinsicType()' for the location of the instantiation.

I also changed the formatting of 'TypeParamInquiry' to correctly format this
case.  I also added tests for both KIND and LEN type parameter inquiries in
resolve104.f90.

Making these changes revealed an error in resolve89.f90 and caused one of the
error messages in assign04.f90 to be different.

Reviewed By: klausler

Differential Revision: https://reviews.llvm.org/D99892
2021-04-06 15:05:16 -07:00
Kiran Chandramohan
b7ef804807 Revert "[flang] Improve constant folding for type parameter inquiries"
This reverts commit 8c7bf2f93da9b64b07509f67552d592a86260ff5.
2021-04-06 09:13:08 +01:00
Peter Steinfeld
8c7bf2f93d [flang] Improve constant folding for type parameter inquiries
We were not folding type parameter inquiries for the form 'var%typeParam'
where 'typeParam' was a KIND or LEN type parameter of a derived type and 'var'
was a designator of the derived type.  I fixed this by adding code to the
function 'FoldOperation()' for 'TypeParamInquiry's to handle this case.  I also
cleaned up the code for the case where there is no designator.

In order to make the error messages correctly refer to both the points of
declaration and instantiation, I needed to add an argument to the function
'InstantiateIntrinsicType()' for the location of the instantiation.

I also changed the formatting of 'TypeParamInquiry' to correctly format this
case.  I also added tests for both KIND and LEN type parameter inquiries in
resolve104.f90.

Making these changes revealed an error in resolve89.f90 and caused one of the
error messages in assign04.f90 to be different.

Differential Revision: https://reviews.llvm.org/D99892
2021-04-05 16:04:15 -07:00
Peter Steinfeld
ae0d1d2e5c [flang] Fix bogus message on internal subprogram with alternate return
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
2021-01-08 10:14:21 -08:00
peter klausler
df62afd559 [flang] Unsplit COMPLEX operations
COMPLEX negation, addition, subtraction, conversions of kind, and
equality/inequality were represented as component-wise REAL
operations.  It turns out to be easier for lowering if we
do not split and recombine these COMPLEX operations, and it
avoids a potential problem with COMPLEX valued function calls
in these contexts.  So add this suite of operations to the
typed expression representation in place of the component-wise
transformations, and support them in folding.

Differential revision: https://reviews.llvm.org/D91443
2020-11-16 09:39:03 -08:00
peter klausler
4cbfd93a59 [flang] Make TypeParamInquiry monomorphic
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
2020-08-31 15:40:40 -07:00
Tim Keith
1f8790050b [flang] Reformat with latest clang-format and .clang-format
Original-commit: flang-compiler/f18@9fe84f45d7
Reviewed-on: https://github.com/flang-compiler/f18/pull/1094
2020-03-28 21:00:16 -07:00
Caroline Concatto
8670e49901 [flang] [LLVMify F18] Replace the use std::ostream with LLVM streams llvm::ostream
This patch replaces the occurrence of std::ostream by llvm::raw_ostream.
In  LLVM Coding Standards[1] "All new code should use raw_ostream
instead of ostream".[1]

As a consequence, this patch also replaces the use of:
   std::stringstream by llvm::raw_string_ostream or llvm::raw_ostream*
   std::ofstream by llvm::raw_fd_ostream
   std::endl by '\n' and flush()[2]
   std::cout by llvm::outs()   and
   std::cerr by llvm::errs()

It also replaces  std::strerro by llvm::sys::StrError** , but NOT in  Fortran
runtime libraries

*std::stringstream were replaced by llvm::raw_ostream in all methods that
used std::stringstream as a parameter. Moreover, it removes the pointers to
these streams.

[1]https://llvm.org/docs/CodingStandards.html
[2]https://releases.llvm.org/2.5/docs/CodingStandards.html#ll_avoidendl

Signed-off-by: Caroline Concatto <caroline.concatto@arm.com>

Running clang-format-7

Signed-off-by: Caroline Concatto <caroline.concatto@arm.com>

Removing residue of ostream library

Signed-off-by: Caroline Concatto <caroline.concatto@arm.com>

Original-commit: flang-compiler/f18@a3507d44b8
Reviewed-on: https://github.com/flang-compiler/f18/pull/1047
2020-03-19 07:54:36 +00:00
peter klausler
f4faeefe3d [flang] Do not emit a prefix for a default-kind character constant in AsFortran
Original-commit: flang-compiler/f18@4a3db55727
Reviewed-on: https://github.com/flang-compiler/f18/pull/1078
2020-03-17 12:35:31 -07:00
peter klausler
38ebace5b7 [flang] Complete formatting of pointer assignments, move to formatting.cpp with rest of AsFortran
Original-commit: flang-compiler/f18@9625317ee8
Reviewed-on: https://github.com/flang-compiler/f18/pull/1073
2020-03-13 09:52:15 -07:00
CarolineConcatto
64ab3302d5 [flang] [LLVMify F18] Compiler module folders should have capitalised names (flang-compiler/f18#980)
This patch renames the modules in f18 to use a capital letter in the
module name

Signed-off-by: Caroline Concatto <caroline.concatto@arm.com>

Original-commit: flang-compiler/f18@d2eb7a1c44
Reviewed-on: https://github.com/flang-compiler/f18/pull/980
2020-02-25 07:11:52 -08:00