[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:37:55 PDT 2023


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

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.

>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] [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>>



More information about the flang-commits mailing list