[flang-commits] [flang] [flang] Adjust semantics of the char length of an array constructor (PR #97337)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Mon Jul 1 12:11:31 PDT 2024


https://github.com/klausler created https://github.com/llvm/llvm-project/pull/97337

An implied DO loop with no trips in an array constructor does not have a well-defined character length unless its data items have a length that is constant expression.  That works, but the implementation is too broadly applied.  An array constructor with an explicit type-spec always has a well-defined length.

>From 1e19ecf182153d086716dc2ec46e17310780b8a1 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Mon, 1 Jul 2024 12:05:43 -0700
Subject: [PATCH] [flang] Adjust semantics of the char length of an array
 constructor

An implied DO loop with no trips in an array constructor does not have
a well-defined character length unless its data items have a length that
is constant expression.  That works, but the implementation is too broadly
applied.  An array constructor with an explicit type-spec always has a
well-defined length.
---
 flang/lib/Semantics/expression.cpp              | 3 ++-
 flang/test/Lower/HLFIR/array-ctor-character.f90 | 9 +++++----
 flang/test/Semantics/array-constr-len.f90       | 1 -
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 2202639a92e43..897e94966a134 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -1584,7 +1584,8 @@ class ArrayConstructorContext {
   std::optional<Expr<SubscriptInteger>> LengthIfGood() const {
     if (type_) {
       auto len{type_->LEN()};
-      if (len && IsConstantExpr(*len) && !ContainsAnyImpliedDoIndex(*len)) {
+      if (explicitType_ ||
+          (len && IsConstantExpr(*len) && !ContainsAnyImpliedDoIndex(*len))) {
         return len;
       }
     }
diff --git a/flang/test/Lower/HLFIR/array-ctor-character.f90 b/flang/test/Lower/HLFIR/array-ctor-character.f90
index 85e6ed27fe077..881085b370ffe 100644
--- a/flang/test/Lower/HLFIR/array-ctor-character.f90
+++ b/flang/test/Lower/HLFIR/array-ctor-character.f90
@@ -93,10 +93,11 @@ subroutine test_set_length_sanitize(i, c1)
   call takes_char([character(len=i):: c1])
 end subroutine
 ! CHECK-LABEL:   func.func @_QPtest_set_length_sanitize(
-! CHECK:   %[[VAL_6:.*]]:2 = hlfir.declare {{.*}}Ec1
-! CHECK:   %[[VAL_9:.*]]:2 = hlfir.declare {{.*}}Ei
-! CHECK:   %[[VAL_25:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref<i64>
+! CHECK:   %[[VAL_2:.*]]:2 = hlfir.declare {{.*}}Ec1
+! CHECK:   %[[VAL_3:.*]]:2 = hlfir.declare %arg0
+! CHECK:   %[[VAL_4:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i64>
+! CHECK:   %[[VAL_25:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i64>
 ! CHECK:   %[[VAL_26:.*]] = arith.constant 0 : i64
 ! CHECK:   %[[VAL_27:.*]] = arith.cmpi sgt, %[[VAL_25]], %[[VAL_26]] : i64
 ! CHECK:   %[[VAL_28:.*]] = arith.select %[[VAL_27]], %[[VAL_25]], %[[VAL_26]] : i64
-! CHECK:   %[[VAL_29:.*]] = hlfir.set_length %[[VAL_6]]#0 len %[[VAL_28]] : (!fir.boxchar<1>, i64) -> !hlfir.expr<!fir.char<1,?>>
+! CHECK:   %[[VAL_29:.*]] = hlfir.set_length %[[VAL_2]]#0 len %[[VAL_28]] : (!fir.boxchar<1>, i64) -> !hlfir.expr<!fir.char<1,?>>
diff --git a/flang/test/Semantics/array-constr-len.f90 b/flang/test/Semantics/array-constr-len.f90
index a785c9e2ece6d..4de9c76c7041c 100644
--- a/flang/test/Semantics/array-constr-len.f90
+++ b/flang/test/Semantics/array-constr-len.f90
@@ -10,6 +10,5 @@ subroutine subr(s,n)
   print *, [(s(1:j),j=1,0)]
   print *, [(s(1:1),j=1,0)] ! ok
   print *, [character(2)::(s(1:n),j=1,0)] ! ok
-  !ERROR: Array constructor implied DO loop has no iterations and indeterminate character length
   print *, [character(n)::(s(1:n),j=1,0)]
 end



More information about the flang-commits mailing list