[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 08:39:42 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-fir-hlfir

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/68598.diff


2 Files Affected:

- (modified) flang/lib/Lower/ConvertVariable.cpp (+8-6) 
- (modified) flang/test/Lower/HLFIR/statement-functions.f90 (+14) 


``````````diff
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>>

``````````

</details>


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


More information about the flang-commits mailing list