[flang-commits] [flang] 351b42a - [flang] Fix folding of character array kind conversion

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Tue Aug 8 11:38:03 PDT 2023


Author: Peter Klausler
Date: 2023-08-08T11:26:38-07:00
New Revision: 351b42a2fd33e60daeb01e7a9c9e1aeaa9fc9365

URL: https://github.com/llvm/llvm-project/commit/351b42a2fd33e60daeb01e7a9c9e1aeaa9fc9365
DIFF: https://github.com/llvm/llvm-project/commit/351b42a2fd33e60daeb01e7a9c9e1aeaa9fc9365.diff

LOG: [flang] Fix folding of character array kind conversion

The folding of conversions of character arrays from one kind to
another was not preserving the value of the character length expression
on the intermediate array constructor, causing spurious errors
when defining named constant arrays of one kind of character with
arrays of another kind.

Fixes llvm-test-suite/Fortran/gfortran/regression/widechar_10.f90.

Differential Revision: https://reviews.llvm.org/D157340

Added: 
    flang/test/Evaluate/folding31.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 544a0b67a49598..aaa13ec371753c 100644
--- a/flang/lib/Evaluate/fold-implementation.h
+++ b/flang/lib/Evaluate/fold-implementation.h
@@ -1349,6 +1349,7 @@ std::optional<Expr<T>> FromArrayConstructor(
 template <typename RESULT, typename OPERAND>
 std::optional<Expr<RESULT>> MapOperation(FoldingContext &context,
     std::function<Expr<RESULT>(Expr<OPERAND> &&)> &&f, const Shape &shape,
+    [[maybe_unused]] std::optional<Expr<SubscriptInteger>> &&length,
     Expr<OPERAND> &&values) {
   ArrayConstructor<RESULT> result{values};
   if constexpr (common::HasMember<OPERAND, AllIntrinsicCategoryTypes>) {
@@ -1369,6 +1370,11 @@ std::optional<Expr<RESULT>> MapOperation(FoldingContext &context,
       result.Push(Fold(context, f(std::move(scalar))));
     }
   }
+  if constexpr (RESULT::category == TypeCategory::Character) {
+    if (length) {
+      result.set_LEN(std::move(*length));
+    }
+  }
   return FromArrayConstructor(context, std::move(result), shape);
 }
 
@@ -1506,9 +1512,9 @@ auto MapOperation(FoldingContext &context,
   return FromArrayConstructor(context, std::move(result), shape);
 }
 
-template <typename DERIVED, typename RESULT, typename LEFT, typename RIGHT>
+template <typename DERIVED, typename RESULT, typename... OPD>
 std::optional<Expr<SubscriptInteger>> ComputeResultLength(
-    Operation<DERIVED, RESULT, LEFT, RIGHT> &operation) {
+    Operation<DERIVED, RESULT, OPD...> &operation) {
   if constexpr (RESULT::category == TypeCategory::Character) {
     return Expr<RESULT>{operation.derived()}.LEN();
   }
@@ -1529,7 +1535,8 @@ auto ApplyElementwise(FoldingContext &context,
   if (expr.Rank() > 0) {
     if (std::optional<Shape> shape{GetShape(context, expr)}) {
       if (auto values{AsFlatArrayConstructor(expr)}) {
-        return MapOperation(context, std::move(f), *shape, std::move(*values));
+        return MapOperation(context, std::move(f), *shape,
+            ComputeResultLength(operation), std::move(*values));
       }
     }
   }

diff  --git a/flang/test/Evaluate/folding31.f90 b/flang/test/Evaluate/folding31.f90
new file mode 100644
index 00000000000000..6b1682b1ee25c1
--- /dev/null
+++ b/flang/test/Evaluate/folding31.f90
@@ -0,0 +1,6 @@
+! RUN: %python %S/test_folding.py %s %flang_fc1
+! Test folding of character array conversion.
+module m
+  character(*,4), parameter :: str4arr(1) = ['a']
+  logical, parameter :: test = str4arr(1) == 4_'a'
+end


        


More information about the flang-commits mailing list