Implement constant folding for LCOBOUND and UCOBOUND intrinsic
functions. Moves some error detection code from intrinsics.cpp to
fold-integer.cpp so that erroneous calls get properly flagged and
converted into known errors.
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.
I recently added support for the extension intrinsic functions INT2 and
INT8, and took the shortcut of defining them as specific intrinsic
functions that map to the standard INT() with hard-wired KIND= values
for the result. This works fine for references to these functions, but
leads to a compiler crash for an attempt to use their names in contexts
other than calling them, since their argument types aren't restricted to
single types and no concrete interface can be characterized for them. So
move them out of the table of specific intrinsic functions and into the
general table of intrinsics, and then handle them afterwards as if they
had been INT().
Fixes https://github.com/llvm/llvm-project/issues/115324.
(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().
The code that deals with the special case of RANK(assumed-rank) in
intrinsic function folding wasn't handling the even more special case of
assumed-type assumed-rank dummy arguments.
A couple of intrinsic functions have optional arguments. Don't insert
type conversions on those arguments when the actual arguments may not be
present at execution time, due to being OPTIONAL, allocatables, or
pointers.
When the second argument to these intrinsic functions is a scalar
constant zero, emit a warning (if enabled) even if the first argument is
not a constant.
…Warn()
Many warning messages were being emitted unconditionally. Ensure that
all warnings are conditional on a true result from a call to
common::LanguageFeatureControl::ShouldWarn() so that it is easy for a
driver to disable them all, or, in the future, to provide per-warning
control over them.
Address TODOs in the intrinsic module ISO_FORTRAN_ENV, and extend the
implementation of NUMERIC_STORAGE_SIZE so that the calculation of its
value is deferred until it is needed so that the effects of
-fdefault-integer-8 or -fdefault-real-8 are reflected. Emit a warning
when NUMERIC_STORAGE_SIZE is used from the module file and the default
integer and real sizes do not match.
Fixes https://github.com/llvm/llvm-project/issues/87476.
This fixes 73c646a3b27293f8cb4ba120de7bc01c223b4b5f.
I misread the #ifdefs and didn't realise that they were in
the middle of passing parameters to a function.
Move the workaround outside this.
\llvm\flang\lib\Evaluate\fold-integer.cpp(705,35): warning: lambda capture 'FromInt64' is not used [-Wunused-lambda-capture]
It is intentionally unused.
Detect NaN elements in data and handle them like gfortran does (at
runtime); namely, NaN can be returned if all the data are NaNs, but any
non-NaN value is preferable. Ensure that folding returns the same
results as runtime computation.
Fixes llvm-test-suite/Fortran/gfortran/regression/maxloc_2.f90 (and
probably others).
The compiler will now emit an error for length == 0 and an
off-by-default portability warning for length > 1. Previously, the
message was an unconditional warning for length /= 1.
Fold references to the (relatively new) intrinsic function NORM2 at
compilation time when the argument(s) are all constants. (Getting this
done right involved some changes to the API of the accumulator function
objects used by the DoReduction<> template, which rippled through some
other reduction function folding code.)
Fortran allows an earlier-declared KIND type parameter of a parameterized
derived type to be used in the constant expression defining the integer
kind of a later type parameter.
TYPE :: T(K,L)
INTEGER, KIND :: K
INTEGER(K), LEN :: L
...
END TYPE
Differential Revision: https://reviews.llvm.org/D159044https://reviews.llvm.org/D159044
Generalize FoldMerge() to accommodate derived type arguments and results,
rename it into Folder<T>::MERGE(), and remove it from the various
FoldIntrinsicFunction() routines for intrinsic types.
Fixes llvm-test-suite/Fortran/gfortran/regression/merge_init_expr_2.f90.
Differential Revision: https://reviews.llvm.org/D157345
Folding of LBOUND/UBOUND on assumed-rank arrays could lead to bogus errors
later. This is a regression from a recent change intended to ensure that
patently bad DIM= arguments were caught even in the case of assumed-rank.
Rearrange the order of checks so that those bad DIM= argument values are
caught but otherwise defer LBOUND/UBOUND of assumed-rank arguments to
run time. (It was tempting to always fold LBOUND(ar,DIM=n) to 1, but
that would obscure the run time error required when 'n' is out of bounds,
including the case of a scalar 'ar'.)
Differential Revision: https://reviews.llvm.org/D156755
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
DIM= arguments with constant values can be checked for validity
even when other arguments to an intrinsic function can't be
folded. Handle errors with assumed-rank arguments as well.
Differential Revision: https://reviews.llvm.org/D155964
Don't emit bogus compile-time error messages about out-of-range values
for the DIM= argument to LBOUND/BOUND when the array in question is an
assumed-rank dummy array argument.
Differential Revision: https://reviews.llvm.org/D155494
Apply compile-time checks to the values supplied for the POS and LEN
arguments of the IBITS intrinsic function even when only one of them
is a known constant.
Differential Revision: https://reviews.llvm.org/D154376
When a LEN type parameter of one PDT is being used as the value
of a LEN type parameter in another PDT, expression rewriting can
loop infinitely due to an incorrect assumption that the same PDT's
parameters are being referenced.
Fixes LLVM bug https://github.com/llvm/llvm-project/issues/63198
Differential Revision: https://reviews.llvm.org/D153465
The code that visits all pairs of constant SHIFT= and SIZE= arguments
in an array-valued call to the ISHFTC intrinsic function had a bad loop
test that affected the case where one of these arguments was scalar and
the other was not. Fix it, and add tests.
Differential Revision: https://reviews.llvm.org/D145092
Previously COUNT would cast the mask input to logical<4> before passing it
to the runtime function, this has been changed to allow different types of logical.
Reviewed By: tblah
Differential Revision: https://reviews.llvm.org/D144867
The intrinsic function DIM can overflow when its second argument
is negative. Detect this case for real and integer arguments and
emit a warning when necessary.
Differential Revision: https://reviews.llvm.org/D143798
When some arguments that specify bit positions, shift counts, and field sizes are
constant at compilation time, but other arguments are not constant, the compiler
should still validate the constant ones. In the current sources, validation is
only performed for intrinsic references that can be folded to constants.
Differential Revision: https://reviews.llvm.org/D140152
The semantics of many transformational intrinsic functions, especially
reductions like SUM(), are determined by the static presence or absence
of a DIM= argument. In the case of an actual DIM= argument that is
syntactically present but could be dynamically absent at execution time
(due to being OPTIONAL, POINTER, or ALLOCATABLE), f18 should emit some
kind of diagnostic message.
Other compilers either ignore this possibility or treat it as a hard
error; neither really seems correct, so let's do something more nuanced.
For cases where the dynamic absence of a value for DIM doesn't pose
as much of a risk because it lowering is going to assume that it's
equal to 1 anyway, emit only a portability warning.
For other cases where the generated code or runtime support library
will need the value of DIM= during execution, emit a warning that
the use of an OPTIONAL/POINTER/ALLOCATABLE variable or component
here is dicey and should be reconsidered.
While here, also catch bad constant DIM= values.
Differential Revision: https://reviews.llvm.org/D139155
Previous attempt to work around a bogus error from MSVC 14 on
code from a recent patch failed, so add an #ifdef and disable
the feature for MSVC builds to get the build bot back up.
When the compile-time result value of a reference to an integer-valued intrinsic
function COUNT, ICHAR, IACHAR, INDEX, SCAN, or VERIFY cannot be represented in
the selected result kind, emit a warning.
Differential Revision: https://reviews.llvm.org/D136974
Compile fix for Microsoft Visual Studio 17.3 (msvc 14.33.31629) which regressed from 17.1.
The compile error is:
```
llvm-project\flang\lib\Evaluate\fold-integer.cpp(802,41): error C2672: 'invoke': no matching overloaded function found
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\include\type_traits(1552,19): message : could be 'unknown-type std::invoke(_Callable &&,_Ty1 &&,_Types2 &&...) noexcept(<expr>)'
llvm-project\flang\lib\Evaluate\fold-integer.cpp(802,41): message : Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Ty1 &&,_Types2 &&...) noexcept(<expr>)'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\include\type_traits(1552): message : see declaration of 'std::invoke'
llvm-project\flang\lib\Evaluate\fold-integer.cpp(490,1): message : With the following template arguments:
llvm-project\flang\lib\Evaluate\fold-integer.cpp(490,1): message : '_Callable=int (__cdecl Fortran::evaluate::value::Integer<16,true,16,unsigned short,unsigned int>::* &)(void) const'
llvm-project\flang\lib\Evaluate\fold-integer.cpp(490,1): message : '_Ty1=const Fortran::evaluate::value::Integer<8,true,8,unsigned char,unsigned short> &'
llvm-project\flang\lib\Evaluate\fold-integer.cpp(490,1): message : '_Types2={}'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\include\type_traits(1546,19): message : or 'unknown-type std::invoke(_Callable &&) noexcept(<expr>)'
C:\Users\meinersbur\src\llvm-project\flang\lib\Evaluate\fold-integer.cpp(802,41): message : 'unknown-type std::invoke(_Callable &&) noexcept(<expr>)': expects 1 arguments - 2 provided
```
For some reason, msvc thinks that the lambda argument is `Scalar<T>` instead of `Scalar<TI>` as declared. This only happens in nested closures, using a lambda without `[]` arguments makes the problem disappear. Using `auto` instead to automatically derive the type fixes the problem.
I recently updated the version of Visual Studio on [[ https://lab.llvm.org/buildbot/#/builders/172 | flang-x86_64-windows buildbot ]] which since then fails because of this problem. It occasionally failed with 'fatal error C1001: Internal compiler error." internal error which I hoped to fix with an update.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D132594
Support these legacy extension intrinsic functions with unambiguous
semantics in those existing compilers that support them by means
of recognizing them as aliases for standard intrinsics (IMAG) or
with simple rewrites (IZEXT, JZEXT). Note that ZEXT has different
semantics in different existing compilers, so we will not support it
due to lack of a broad unambiguous precedent.
Differential Revision: https://reviews.llvm.org/D132154
The integer arithmetic template supports ISHFTC() but the
integer intrinsic folding code had yet to call it; finish
the job.
Differential Revision: https://reviews.llvm.org/D130379
Create a TargetCharacteristics class to centralize the few items of
target specific information that are relevant to semantics. Use the
new class for all target queries, including derived type component layout
modeling.
Future work will initialize this class with target information
provided or forwarded by the drivers, and use it to fold layout-dependent
intrinsic functions like TRANSFER().
Differential Revision: https://reviews.llvm.org/D129018
Updates: Attempts to work around build issues on Windows.
For example, FINDLOC(A,X) should convert both A and X to COMPLEX(8)
if the operands are REAL(8) and COMPLEX(4), so that comparisons
can be done without losing inforation. The current implementation
unconditionally converts X to the type of the array A.
Differential Revision: https://reviews.llvm.org/D127030
Previously MASK= elements were accessed in assumption that mask is an array of
input argument rank (and in combination with explicit DIM= argument we had
out-of-bounds access), but for MAXLOC/MINLOC/FINDLOC mask should be be
conformable and could be scalar.
Add new regression tests with scalar mask for verification.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D124408
Similarly to LBOUND in https://reviews.llvm.org/D123237, fix UBOUND() folding
for constant arrays (for both w/ and w/o DIM=): convert
GetConstantArrayLboundHelper into common helper class for both lower/upper
bounds.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D123520
Set LBOUND() constant folding for parentheses expr. as ones
Array bounds should not propagate throught omitted bounds specifications or
temporary variables - fix constant folding in case of Parentheses<T> expression
by explicitly returning array of ones (or scalar in case of DIM=).
Add set of tests for (x) bounds checks (w/ and w/o 'parameter' arrays)
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D123838
Previously constant folding uses 'dim' without checks which leads to ICE if we
do not have DIM= parameter. And for inputs without DIM= we need to form an
array of rank size with computed bounds instead of single value.
Add additional PackageConstant function to simplify 'if (dim)' handling since we
need to distinguish between scalar initialization in case of DIM= argument and
rank=1 array.
Also add a few more tests with 'parameter' type to verify folding for constant
arrays.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D123237
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().