[flang-commits] [flang] ec6b2c6 - [flang] Fold character array constructor with unknown length (#123983)
via flang-commits
flang-commits at lists.llvm.org
Mon Jan 27 08:57:02 PST 2025
Author: Peter Klausler
Date: 2025-01-27T08:56:58-08:00
New Revision: ec6b2c63d93d8f8edeafcc7330d0b2349463d73d
URL: https://github.com/llvm/llvm-project/commit/ec6b2c63d93d8f8edeafcc7330d0b2349463d73d
DIFF: https://github.com/llvm/llvm-project/commit/ec6b2c63d93d8f8edeafcc7330d0b2349463d73d.diff
LOG: [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.
Added:
flang/test/Evaluate/bug123766.f90
Modified:
flang/lib/Evaluate/fold-implementation.h
Removed:
################################################################################
diff --git a/flang/lib/Evaluate/fold-implementation.h b/flang/lib/Evaluate/fold-implementation.h
index 4dcc737688ca07..b0f39e63d0941f 100644
--- a/flang/lib/Evaluate/fold-implementation.h
+++ b/flang/lib/Evaluate/fold-implementation.h
@@ -1267,6 +1267,12 @@ template <typename T> class ArrayConstructorFolder {
explicit ArrayConstructorFolder(FoldingContext &c) : context_{c} {}
Expr<T> FoldArray(ArrayConstructor<T> &&array) {
+ if constexpr (T::category == TypeCategory::Character) {
+ if (const auto *len{array.LEN()}) {
+ charLength_ = ToInt64(Fold(context_, common::Clone(*len)));
+ knownCharLength_ = charLength_.has_value();
+ }
+ }
// Calls FoldArray(const ArrayConstructorValues<T> &) below
if (FoldArray(array)) {
auto n{static_cast<ConstantSubscript>(elements_.size())};
@@ -1274,12 +1280,9 @@ template <typename T> class ArrayConstructorFolder {
return Expr<T>{Constant<T>{array.GetType().GetDerivedTypeSpec(),
std::move(elements_), ConstantSubscripts{n}}};
} else if constexpr (T::category == TypeCategory::Character) {
- if (const auto *len{array.LEN()}) {
- auto length{Fold(context_, common::Clone(*len))};
- if (std::optional<ConstantSubscript> lengthValue{ToInt64(length)}) {
- return Expr<T>{Constant<T>{
- *lengthValue, std::move(elements_), ConstantSubscripts{n}}};
- }
+ if (charLength_) {
+ return Expr<T>{Constant<T>{
+ *charLength_, std::move(elements_), ConstantSubscripts{n}}};
}
} else {
return Expr<T>{
@@ -1300,6 +1303,11 @@ template <typename T> class ArrayConstructorFolder {
elements_.emplace_back(c->At(index));
} while (c->IncrementSubscripts(index));
}
+ if constexpr (T::category == TypeCategory::Character) {
+ if (!knownCharLength_) {
+ charLength_ = std::max(c->LEN(), charLength_.value_or(-1));
+ }
+ }
return true;
} else {
return false;
@@ -1349,6 +1357,8 @@ template <typename T> class ArrayConstructorFolder {
FoldingContext &context_;
std::vector<Scalar<T>> elements_;
+ std::optional<ConstantSubscript> charLength_;
+ bool knownCharLength_{false};
};
template <typename T>
diff --git a/flang/test/Evaluate/bug123766.f90 b/flang/test/Evaluate/bug123766.f90
new file mode 100644
index 00000000000000..b58989e6c26d85
--- /dev/null
+++ b/flang/test/Evaluate/bug123766.f90
@@ -0,0 +1,5 @@
+! RUN: %python %S/test_folding.py %s %flang_fc1
+character(10), parameter :: a = '0123456789'
+character(3), parameter :: arr(3) = [(a(1:i), i=1,3)]
+logical, parameter :: test1 = all(arr == ["0", "01", "012"])
+end
More information about the flang-commits
mailing list