Commit Graph

238 Commits

Author SHA1 Message Date
Andre Kuhlenschmidt
83b462af17 [flang][CLI] Have the CLI hint the flag to disable a warning (#144767)
Adds a hint to the warning message to disable a warning and updates the
tests to expect this.

Also fixes a bug in the storage of canonical spelling of error flags so
that they are not used after free.
2025-06-30 10:17:05 -07:00
Peter Klausler
a6432b971a [flang] Fix folding of SHAPE(SPREAD(source,dim,ncopies=-1)) (#141146)
The number of copies on the new dimension must be clamped via MAX(0,
ncopies) so that it is no less than zero.

Fixes https://github.com/llvm/llvm-project/issues/141119.
2025-05-28 14:01:10 -07:00
Peter Klausler
efd7caac2e [flang] IEEE_SUPPORT_FLAG(..., LOCAL) in specification expression (#134270)
The optional second argument to IEEE_SUPPORT_FLAG (and related functions
from the intrinsic IEEE_ARITHMETIC module) is needed only for its type,
not its value. Restrictions on local objects as arguments to function
references in specification expressions shouldn't apply to it.

Define a new attribute for dummy data object characteristics to
distinguish such arguments, set it for the appropriate intrinsic
function references, and test it during specification expression
validation.
2025-04-04 08:43:25 -07:00
Peter Klausler
79a25e11fe [flang] Further work on NULL(MOLD=allocatable) (#129345)
Refine handling of NULL(...) in semantics to properly distinguish
NULL(), NULL(objectPointer), NULL(procPointer), and NULL(allocatable)
from each other in relevant contexts.

Add IsNullAllocatable() and IsNullPointerOrAllocatable() utility
functions. IsNullAllocatable() is true only for NULL(allocatable); it is
false for a bare NULL(), which can be detected independently with
IsBareNullPointer().

IsNullPointer() now returns false for NULL(allocatable).

ALLOCATED(NULL(allocatable)) now works, and folds to .FALSE.

These utilities were modified to accept const pointer arguments rather
than const references; I usually prefer this style when the result
should clearly be false for a null argument (in the C sense), and it
helped me find all of their use sites in the code.
2025-03-03 14:46:35 -08:00
jeanPerier
06f4fe3317 [flang][NFC] fix rewrite-out_of_range.F90 tests (#126699)
There was a typo in the target, and REAL(16) parts needed to be
protected too.
2025-02-11 11:49:32 +01:00
vdonaldson
79e9887a0f [flang] test fix (#126251) 2025-02-07 09:55:10 -05:00
klensy
c491cbfe75 [flang][test] Fix filecheck annotation typos (#92387) 2025-02-05 18:24:47 +00:00
jeanPerier
925d347c5a [flang] fix IsSimplyContiguous with expressions (#125708)
IsSymplyContiguous was visiting expressions and returning false on
expressions like `x(::2) + y`, which triggered an assert in lowering
when preparing arguments for copy-in/out.

Update it to return false for everything that is not a variable, except
when provided a flag to treat PARAMETER bases as variables. This flags
is required for internal usages in lowering where lowering needs to now
if the read-only memory is being addressed contiguously or not.

Update call lowering to always copy parameter array section into
contiguous writable memory when passing them. The rational here is that
copy-out generated in nested calls using the dummy arguments will cause
a segfault.
2025-02-05 17:20:35 +01:00
Peter Klausler
2bfb3bae69 [flang] Make REAL/COMPLEX(10) a hard error for non-x86 targets (#124655)
Currently the use of REAL/COMPLEX(KIND=10) as a type or literal constant
suffix elicits an optional warning message only. This leads to compiler
internal errors during lowering when these types appear in code being
compiled to non-x86_64 targets. For better error messaging, make the use
of these types a hard error in semantics instead when they are not
supported by the target architecture.
2025-01-31 11:43:29 -08:00
Peter Klausler
10b0a07e11 [flang] Fold KIND= arguments in intrinsic function references (#124666)
KIND= arguments in e.g. ACHAR(..., KIND=...) intrinsic function
references must be compilation-time constant expressions. The compiler
was failing to evaluate those expressions if they were not actually
literaly constant values.

Fixes https://github.com/llvm/llvm-project/issues/124618.
2025-01-31 10:53:14 -08:00
Peter Klausler
e252c40210 [flang] Fix spurious error due to bad expression shape calculation (#124323)
GetShape() needed to be called with a FoldingContext in order to
properly construct an extent expression for the shape of an array
constructor whose elements (nested in an implied DO loop) were not
scalars.

Fixes https://github.com/llvm/llvm-project/issues/124191.
2025-01-27 08:59:43 -08:00
Peter Klausler
ec6b2c63d9 [flang] Fold character array constructor with unknown length (#123983)
When a character array constructor does not have an explicit type with a
constant length, the compiler can still fold it if all of its elements
are constants. These array constructors will have been wrapped up in the
internal %SET_LENGTH operation, which will determine the final length of
the folded value, so use the maximum length of the constant elements as
the length of the folded array constructor.

Fixes https://github.com/llvm/llvm-project/issues/123766.
2025-01-27 08:56:58 -08:00
Peter Klausler
73f9034036 [flang] Fix failure to fold character array (#123418)
When a character component reference is applied to a constant array of
derived type, ensure that the length of the resulting character array is
properly defined.

Fixes https://github.com/llvm/llvm-project/issues/123362.
2025-01-27 08:46:02 -08:00
vdonaldson
c28a7c1efd [flang] Modifications to ieee_support_halting (#120747)
The F23 standard requires that a call to intrinsic module procedure
ieee_support_halting be foldable to a constant at compile time in some
contexts. See for example F23 Clause 10.1.11 [Specification expression]
list item (13), Clause 1.1.12 [Constant expression] list item (11), and
references to specification and constant expressions elsewhere, such as
constraints C1012, C853, and C704.

Some Arm processors allow a user to control processor behavior when an
arithmetic exception is signaled, and some Arm processors do not have
this capability. An Arm executable will run on either type of processor,
so it is effectively unknown at compile time whether or not this support
will be available at runtime. This in conflict with the standard
requirement.

This patch addresses this conflict by implementing ieee_support_halting
calls on Arm processors to check if this capability is present at
runtime. A call to ieee_support_halting in a constant context, such as
in the specification part of a program unit, will generate a compile
time "cannot be computed as a constant value" error. The expectation is
that such calls are unlikely to appear in production code.

Code generation for other processors will continue to generate a compile
time constant result for ieee_support_halting calls.
2024-12-23 09:30:45 -05: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
vdonaldson
df43af40ec Vkd1 (#118721) 2024-12-04 19:16:49 -05:00
vdonaldson
17f99accf2 [flang] build test fix/suppression (#118716) 2024-12-04 18:47:45 -05:00
vdonaldson
6003be7ef1 [flang] IEEE_GET_UNDERFLOW_MODE, IEEE_SET_UNDERFLOW_MODE (#118551)
Implement IEEE_GET_UNDERFLOW_MODE and IEEE_SET_UNDERFLOW_MODE. Update
IEEE_SUPPORT_UNDERFLOW_CONTROL to enable support for indvidual REAL
kinds.
2024-12-04 16:21:11 -05:00
Peter Klausler
376713ff50 [flang] Accept CLASS(*) array in EOSHIFT (#116114)
The intrinsic processing code wasn't allowing the ARRAY= argument to the
EOSHIFT intrinsic function to be CLASS(*). That case seems to conform to
the standard, although only one compiler could actually handle it, so
allow for it.

Fixes https://github.com/llvm/llvm-project/issues/115923.
2024-11-14 14:58:19 -08:00
Peter Klausler
17daa84348 [flang] Better IS_CONTIGUOUS folding for substrings (#115970)
At present, the compiler doesn't analyze substring references for
contiguity. But there are cases where substrings can be known to be
contiguous (scalar base, empty substring, or complete substring) or can
be known to be discontiguous, and references to the intrinsic function
IS_CONTIGUOUS in those cases may appear in constant expressions.

Fixes https://github.com/llvm/llvm-project/issues/115675.
2024-11-14 14:58:01 -08:00
Peter Klausler
ebc0163cea [flang] INT2 & INT8 can't be specific intrinsic functions (#115360)
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.
2024-11-14 14:57:19 -08:00
vdonaldson
592c0fe55f [flang] Tweak a SCALE/IEEE_SCALB folding overflow warning message (#114994) 2024-11-05 13:43:41 -05:00
Peter Klausler
38b9dd7a7f [flang] Fold ERFC_SCALED (#112287)
Move the ErfcScaled template function from the runtime into a new header
file in flang/include/Common, then use it in constant folding to
implement folding for the erfc_scaled() intrinsic function.
2024-10-15 14:23:15 -07:00
Peter Klausler
1759f3b404 [flang] Improve error messages about overflowed integer conversions (#110031)
When an INTEGER conversion to a smaller kind overflows in constant
folding, report the truncated value so that it makes more sense later if
it shows up in other messages.
2024-09-30 12:38:06 -07:00
Peter Klausler
6959ec91d7 [flang] Extension intrinsics INT8 and INT2 (#109433)
These are legacy conversion intrinsic functions supported by nearly all
Fortran compilers (esp. INT8).
They are equivalent to INT(..., KIND=8 or 2), respectively.
2024-09-20 13:53:50 -07:00
Peter Klausler
50d15e688f [flang] Subnormal arguments to and results from SPACING (#108861)
The standards aren't clear about how IEEE-754 subnormal values interact
with the intrinsic function SPACING. Four compilers interpret the
standard such that SPACING(x) will return a value never less than
TINY(x); one compiler returns TINY(x) for ABS(x) <= TINY(x) but can
return SPACING(x) < TINY(x) for some ABS(x) > TINY(x); one other
compiler works similarly, but also oddly returns SPACING(x) < TINY(x)
for ABS(x) >= TINY(x)/2.

Follow the most common precedent.
2024-09-16 13:46:12 -07:00
Peter Klausler
37f94cd99a [flang] Accept KIND(x) when x is assumed-rank (#107787)
Don't emit a bogus error about being unable to forward an assumed-rank
dummy argument as an actual argument in the case of the KIND intrinsic
function.

Fixes https://github.com/llvm/llvm-project/issues/107782.
2024-09-10 14:14:33 -07:00
Tom Eccles
3b19e480c0 [flang] Warn when F128 is unsupported (#102147) (#106957)
This generates `warning: REAL(KIND=16) is not an enabled type for this
target` if that type is used in a build not correctly configured to
support this type. Uses of `selected_real_kind(30)` return -1.

Relanding #102147 because the test errors turned out to be specific to a
downstream configuration.
2024-09-05 15:59:36 +01:00
Tom Eccles
8ae877a089 Revert "[flang] Warn when F128 is unsupported" (#106561)
Reverts llvm/llvm-project#102147

It seems some systems which should support F128 are wrongly detected as
not supporting.

This might be due to checking `LDBL_MANT_DIG` instead of
`__LDBL_MANT_DIG__`. I will investigate.
2024-08-29 15:37:59 +01:00
Tom Eccles
114ff99e93 [flang] Warn when F128 is unsupported (#102147)
This generates `warning: REAL(KIND=16) is not an enabled type for this
target` if that type is used in a build not correctly configured to
support this type. Uses of `selected_real_kind(30)` return -1.
2024-08-28 16:33:39 +01:00
Peter Klausler
c9a4c51bb0 [flang] Fix test on ppc64le & aarch64 (#105439)
Don't try to fold x87 extended precision operations in a test unless
it's targeting x86-64.
2024-08-20 15:01:07 -07:00
Peter Klausler
0c489863e7 [flang] Disable part of failing test (temporary) (#105350)
A new section of a test is failing on aarch64 and ppc64le; disable it
while I sort things out.
2024-08-20 13:40:04 -07:00
Peter Klausler
1233df7317 [flang] Disable failing test (#105327)
flang/test/Evaluate/fold-nearest.f90 is failing oddly on ppc64le;
disable it for now while I sort things out.
2024-08-20 13:09:30 -07:00
Peter Klausler
1e1cf258c7 [flang] Fix IEEE_NEAREST_AFTER folding edge cases (#104846)
Conversions of infinities from other kinds to real(10) were incorrect,
and comparisons of real(2) vs real(3) are dicey as conversions in one
direction can overflow and conversions in the other can lose precision.
Use real(16) as the common type for comparisons in IEEE_NEAREST_AFTER.
2024-08-20 12:04:57 -07:00
Rainer Orth
b53fe2ca8c [flang][test] Restrict Evaluate/fold-out_of_range.f90 to x86_64 (#102890)
`Flang :: Evaluate/fold-out_of_range.f90` currently `FAIL`s on
Linux/sparc64. This seems to be the same issue that led to disabling the
test on Solaris in 27549ee989. In fact,
the generic Solaris disablement was over-eager: the test `PASS`es just
fine on Solaris/amd64.

Since the use of `REAL*10` makes the test x86-specific, this patch
actually implements that requirement.

Tested on `sparc64-unknown-linux-gnu`, `sparcv9-sun-solaris2.11`,
`amd64-pc-solaris2.11`, and `x86_64-pc-linux-gnu`.
2024-08-13 15:35:51 +02:00
Peter Klausler
90617e99bb [flang] Fix folding edge cases with IEEE_NEXT_{UP/DOWN/AFTER} & NEAREST (#101424)
The generation of 80-bit x87 floating-point infinities was incorrect in
Normalize(), the comparison for IEEE_NEXT_AFTER needs to use the most
precise type of its arguments, and we don't need to warn about overflows
from +/-HUGE() to infinity. Warnings about NaN arguments remain in
place, and enabled by default, as their usage may or may not be
portable, and their appearance in a real code seems most likely to
signify an earlier error.
2024-08-02 12:06:15 -07:00
Peter Klausler
ca305337ff [flang] Fix -fdefault-integer-8 result kind of relations (#101234)
The result of a relational operator is a default logical, which is
LOGICAL(8) under the -fdefault-integer-8 option.

Fixes https://github.com/llvm/llvm-project/issues/101161.
2024-08-02 12:02:45 -07:00
Peter Klausler
ff567a4e04 [flang] Fix folding of RANK(assumed-type assumed-rank) (#101027)
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.
2024-07-30 09:46:26 -07:00
Peter Klausler
6f7e715eae [flang] Don't inject possibly invalid conversions while folding (#100842)
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.
2024-07-30 09:45:34 -07:00
Peter Klausler
33c27f28d1 [flang] Warn about undefined function results (#99533)
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.
2024-07-30 09:41:46 -07:00
vdonaldson
4cdc19b84c [flang] IEEE_NEXT_AFTER, IEEE_NEXT_DOWN, IEEE_NEXT_UP, NEAREST (#100782)
IEEE_ARITHMETIC intrinsic module procedures IEEE_NEXT_AFTER,
IEEE_NEXT_DOWN, and IEEE_NEXT_UP, and intrinsic NEAREST return larger or
smaller values adjacent to their primary REAL argument. The four
procedures vary in how the direction is chosen, in how special cases are
treated, and in what exceptions are generated. Implement the three
IEEE_ARITHMETIC procedures. Update the NEAREST implementation to support
all six REAL kinds 2,3,4,8,10,16, and fix several bugs.

IEEE_NEXT_AFTER(X,Y) returns a NaN when Y is a NaN as that seems to be
the universal choice of other compilers.

Change the front end compile time implementation of these procedures to
return normal (HUGE) values for infinities when applicable, rather than
always returning the input infinity.
2024-07-29 09:22:36 -04:00
Pete Steinfeld
70969df73d [flang] Improve warnings for invalid arguments when folding host runtime (#96807)
This is another attempt at a change that Jean made to Phabricator in
https://reviews.llvm.org/D116934. That attempt ran into problems with
building on Windows.

This change improves the messages that are produced when running into
invalid arguments during constant folding.

Note that the original attempt at implementing this contained additional
code in .../llvm-project/flang/test/Evaluate/folding04.f90:
```
  !WARN: warning: argument 'x' must be strictly positive
  real(8), parameter :: nan_r8_dlog1 = dlog(-0.1_8)
  TEST_ISNAN(nan_r8_dlog1)
```
For reasons I don't understand, this additional code caused the Windows
build to fail. So this new version of the update does not contain that
code.
2024-07-02 08:38:43 -07:00
Peter Klausler
317277e4f9 [flang] Better error reporting for MOD/MODULO/NEAREST (#96114)
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.
2024-06-24 09:21:06 -07:00
jeanPerier
73cf014223 [flang] harden TypeAndShape for assumed-ranks (#96234)
SIZEOF and C_SIZEOF were broken for assumed-ranks because
`TypeAndShape::MeasureSizeInBytes` behaved as a scalar because the
`TypeAndShape::shape_` member was the same for scalar and assumed-ranks.

The easy fix would have been to add special handling in
`MeasureSizeInBytes` for assumed-ranks using the TypeAndShape
attributes, but I think this solution would leave `TypeAndShape::shape_`
manipulation fragile to future developers. Hence, I went for the
solution that turn shape_ into a `std::optional<Shape>`.
2024-06-24 10:21:04 +02:00
Peter Klausler
4b57fe65fd [flang] Fold IEEE_SUPPORT_xxx() intrinsic functions (#95866)
All of the IEEE_SUPPORT_xxx() intrinsic functions must fold to constant
logical values when they have constant arguments; and since they fold to
.TRUE. for currently support architectures, always fold them. But also
put in the infrastructure whereby a driver can initialize Evaluate's
target information to set some of them to .FALSE. if that becomes
necessary.
2024-06-18 12:46:15 -07:00
Peter Klausler
68f4e46c43 [flang] Adjust "doubled operator" expression extension (#93353)
Most Fortran compilers accept "doubled operators" as a language
extension. This is the use of a unary '+' or '-' operator that is not
the first unparenthesized operator in an expression, as in 'x*-y'.

This compiler has implemented this extension, but in a way that's
different from other compilers' behavior. I interpreted the unary
'+'/'-' as a unary operator in the sense of C/C++, giving it a higher
priority than any binary (dyadic) operator.

All other compilers with this extension, however, give a unary '+'/'-' a
lower precedence than exponentiation ('**'), a binary operator that
C/C++ lacks. And this interpretation makes more sense for Fortran,
anyway, where the standard conforming '-x**y' must mean '-(x**y)'
already.

This patch makes 'x*-y**z' parse as 'x*-(y**z)', not 'x*(-y)**z)', and
adds a test to ensure that it does.
2024-06-03 11:58:18 -07:00
Peter Klausler
47b485c052 [flang] Fix type of array constructor triplet (extension) (#92970)
The type of "[lo:hi:str]" is being forced to INTEGER(8), ignoring the
types of the operands to the triplet. The type of a triplet should be
whatever the type of "lo+hi+str" would be.

(Array constructor triplets are a syntactic sugar extension for an
implied DO loop.)
2024-05-23 16:09:45 -07:00
madanial0
8b7f178091 [flang] Fix Failing rewrite-out_of_range testcase to only check for real 10 on supported platforms (#91629)
The real 10 tests fail on `AIX` on `PPC`, only check them on `x86_64`

Co-authored-by: Mark Danial <mark.danial@ibm.com>
2024-05-13 10:40:14 -04:00
Peter Klausler
505f6da196 [flang] Ensure all warning/portability messages are guarded by Should… (#90518)
…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.
2024-05-01 14:33:14 -07:00
Peter Klausler
1444e5acfb [flang] Complete implementation of OUT_OF_RANGE() (#89334)
The intrinsic function OUT_OF_RANGE() lacks support in lowering and the
runtime. This patch obviates a need for any such support by implementing
OUT_OF_RANGE() via rewriting in semantics. This rewriting of
OUT_OF_RANGE() calls replaces the existing code that folds
OUT_OF_RANGE() calls with constant arguments.

Some changes and fixes were necessary outside of OUT_OF_RANGE()'s
folding code (now rewriting code), whose testing exposed some other
issues worth fixing.

- The common::RealDetails<> template class was recoded in terms of a new
base class with a constexpr constructor, so that the the characteristics
of the various REAL kinds could be queried dynamically as well. This
affected some client usage.
- There were bugs in the code that folds TRANSFER() when the type of X
or MOLD was REAL(10) -- this is a type that occupies 16 bytes per
element in execution memory but only 10 bytes (was 12) in the data of
std::vector<Scalar<>> in a Constant<>.
- Folds of REAL->REAL conversions weren't preserving infinities.
2024-04-22 15:46:00 -07:00