[flang-commits] [flang] [flang][hlfir] Cast actual cst len character to stmt func dummy type (PR #68598)

via flang-commits flang-commits at lists.llvm.org
Mon Oct 9 10:05:13 PDT 2023


https://github.com/jeanPerier updated https://github.com/llvm/llvm-project/pull/68598

>From 5b05ef1560f6ce02afe4d9e475a76f144dd60364 Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Mon, 9 Oct 2023 08:31:56 -0700
Subject: [PATCH 1/2] [flang][hlfir] Cast actual cst len character to stmt func
 dummy type

When calling a statement function with a character actual argument with
a constant length mismatching the dummy length, HLFIR lowering created
an hlfir.declare with the actual argument length for the dummy, causing
bugs when lowering the statement function expression.

Ensure character dummies are always cast to the dummy type when lowering
dummy declarations.
---
 flang/lib/Lower/ConvertVariable.cpp            | 14 ++++++++------
 flang/test/Lower/HLFIR/statement-functions.f90 | 14 ++++++++++++++
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index ef1f68f7e0ebc3f..3b2384f07d8a233 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -1947,13 +1947,15 @@ void Fortran::lower::mapSymbolAttributes(
   if (ba.isChar()) {
     if (arg) {
       assert(!preAlloc && "dummy cannot be pre-allocated");
-      if (arg.getType().isa<fir::BoxCharType>()) {
+      if (arg.getType().isa<fir::BoxCharType>())
         std::tie(addr, len) = charHelp.createUnboxChar(arg);
-        // Ensure proper type is given to array/scalar that transited via
-        // fir.boxchar arg.
-        mlir::Type castTy = builder.getRefType(converter.genType(var));
-        addr = builder.createConvert(loc, castTy, addr);
-      }
+      else if (!addr)
+        addr = arg;
+      // Ensure proper type is given to array/scalar that transited via
+      // fir.boxchar arg or is a statement function actual argument with
+      // a different length.
+      mlir::Type castTy = builder.getRefType(converter.genType(var));
+      addr = builder.createConvert(loc, castTy, addr);
     }
     if (std::optional<int64_t> cstLen = ba.getCharLenConst()) {
       // Static length
diff --git a/flang/test/Lower/HLFIR/statement-functions.f90 b/flang/test/Lower/HLFIR/statement-functions.f90
index f66b285ed9452de..d19b912e0fe213c 100644
--- a/flang/test/Lower/HLFIR/statement-functions.f90
+++ b/flang/test/Lower/HLFIR/statement-functions.f90
@@ -33,3 +33,17 @@ subroutine char_test(c, n)
 ! CHECK:  %[[VAL_18:.*]]:2 = hlfir.declare %[[VAL_13]]#0 typeparams %[[VAL_17]] {uniq_name = "_QFchar_testFstmt_funcEchar_stmt_func_dummy_arg"} : (!fir.ref<!fir.char<1,?>>, i32) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
 ! CHECK:  %[[VAL_19:.*]] = arith.constant 10 : i64
 ! CHECK:  %[[VAL_20:.*]] = hlfir.set_length %[[VAL_18]]#0 len %[[VAL_19]] : (!fir.boxchar<1>, i64) -> !hlfir.expr<!fir.char<1,10>>
+
+subroutine char_test2(c)
+  character(10) :: c
+  character(5) :: c_stmt_func
+  character(*), parameter :: padding = "padding"
+  character(len(c_stmt_func)+len(padding)) :: stmt_func
+  stmt_func(c_stmt_func) = c_stmt_func // padding
+  call test(stmt_func(c))
+end subroutine
+! CHECK-LABEL:  func.func @_QPchar_test2(
+! CHECK:    %[[C:.*]]:2 = hlfir.declare %1 typeparams %c10 {uniq_name = "_QFchar_test2Ec"} : (!fir.ref<!fir.char<1,10>>, index) -> (!fir.ref<!fir.char<1,10>>, !fir.ref<!fir.char<1,10>>)
+! CHECK:    %[[CAST:.*]] = fir.convert %[[C]]#0 : (!fir.ref<!fir.char<1,10>>) -> !fir.ref<!fir.char<1,5>>
+! CHECK:    %[[C_STMT_FUNC:.*]]:2 = hlfir.declare %[[CAST]] typeparams %c5{{.*}} {uniq_name = "_QFchar_test2Fstmt_funcEc_stmt_func"} : (!fir.ref<!fir.char<1,5>>, index) -> (!fir.ref<!fir.char<1,5>>, !fir.ref<!fir.char<1,5>>)
+! CHECK:    hlfir.concat %[[C_STMT_FUNC]]#0, %{{.*}} len %{{.*}} : (!fir.ref<!fir.char<1,5>>, !fir.ref<!fir.char<1,7>>, index) -> !hlfir.expr<!fir.char<1,12>>

>From 1f1f856c29c00bdf2396596a83aef1381127e8b8 Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Mon, 9 Oct 2023 10:03:41 -0700
Subject: [PATCH 2/2] update comment

---
 flang/lib/Lower/ConvertVariable.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 3b2384f07d8a233..46a59b38ae6abde 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -1951,9 +1951,9 @@ void Fortran::lower::mapSymbolAttributes(
         std::tie(addr, len) = charHelp.createUnboxChar(arg);
       else if (!addr)
         addr = arg;
-      // Ensure proper type is given to array/scalar that transited via
+      // Ensure proper type is given to array/scalar that was transmitted as a
       // fir.boxchar arg or is a statement function actual argument with
-      // a different length.
+      // a different length than the dummy.
       mlir::Type castTy = builder.getRefType(converter.genType(var));
       addr = builder.createConvert(loc, castTy, addr);
     }



More information about the flang-commits mailing list