[flang-commits] [flang] [Flang] Handle %VAL arguments correctly (PR #157186)
Carlos Seo via flang-commits
flang-commits at lists.llvm.org
Fri Sep 5 14:47:02 PDT 2025
https://github.com/ceseo created https://github.com/llvm/llvm-project/pull/157186
Internal procedures expect reference parameters. However, when %VAL is used, the argument should be passed by value. Create a temporary variable in call generation and pass the address to avoid a type conversion error.
Fixes #118239
>From d7f5c644549df294e790a669154e00ccc1bdc2ef Mon Sep 17 00:00:00 2001
From: Carlos Seo <carlos.seo at linaro.org>
Date: Fri, 5 Sep 2025 21:27:50 +0000
Subject: [PATCH] [Flang] Handle %VAL arguments correctly
Internal procedures expect reference parameters. However, when %VAL is used,
the argument should be passed by value. Create a temporary variable in call
generation and pass the address to avoid a type conversion error.
Fixes #118239
---
flang/lib/Lower/ConvertCall.cpp | 33 ++++++++++++++++---
.../Lower/percent-val-actual-argument.f90 | 14 ++++++++
2 files changed, 42 insertions(+), 5 deletions(-)
create mode 100644 flang/test/Lower/percent-val-actual-argument.f90
diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index 04dcc9250be61..9f71f7417005f 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -494,10 +494,20 @@ Fortran::lower::genCallOpAndResult(
// arguments of any type and vice versa.
mlir::Value cast;
auto *context = builder.getContext();
- if (mlir::isa<fir::BoxProcType>(snd) &&
- mlir::isa<mlir::FunctionType>(fst.getType())) {
- auto funcTy = mlir::FunctionType::get(context, {}, {});
- auto boxProcTy = builder.getBoxProcType(funcTy);
+
+ // Special handling for %VAL arguments: internal procedures expect
+ // reference parameters. When %VAL is used, the argument should be
+ // passed by value. So we need to create a temporary variable and
+ // pass its address to avoid a type conversion error.
+ if (fir::isa_ref_type(snd) && !fir::isa_ref_type(fst.getType()) &&
+ fir::dyn_cast_ptrEleTy(snd) == fst.getType()) {
+ mlir::Value temp = builder.createTemporary(loc, fst.getType());
+ builder.create<fir::StoreOp>(loc, fst, temp);
+ cast = temp;
+ } else if (mlir::isa<fir::BoxProcType>(snd) &&
+ mlir::isa<mlir::FunctionType>(fst.getType())) {
+ mlir::FunctionType funcTy = mlir::FunctionType::get(context, {}, {});
+ fir::BoxProcType boxProcTy = builder.getBoxProcType(funcTy);
if (mlir::Value host = argumentHostAssocs(converter, fst)) {
cast = fir::EmboxProcOp::create(builder, loc, boxProcTy,
llvm::ArrayRef<mlir::Value>{fst, host});
@@ -1637,7 +1647,20 @@ void prepareUserCallArguments(
(*cleanup)();
break;
}
- caller.placeInput(arg, builder.createConvert(loc, argTy, value));
+ // For %VAL arguments, we should pass the value directly without
+ // conversion to reference types. If argTy is different from value type,
+ // it might be due to signature mismatch with internal procedures.
+ if (argTy == value.getType())
+ caller.placeInput(arg, value);
+ else if (fir::isa_ref_type(argTy) &&
+ fir::dyn_cast_ptrEleTy(argTy) == value.getType()) {
+ // We're trying to convert value to reference - create temporary
+ mlir::Value temp = builder.createTemporary(loc, value.getType());
+ builder.create<fir::StoreOp>(loc, value, temp);
+ caller.placeInput(arg, temp);
+ } else
+ caller.placeInput(arg, builder.createConvert(loc, argTy, value));
+
} break;
case PassBy::BaseAddressValueAttribute:
case PassBy::CharBoxValueAttribute:
diff --git a/flang/test/Lower/percent-val-actual-argument.f90 b/flang/test/Lower/percent-val-actual-argument.f90
new file mode 100644
index 0000000000000..736baa0eca21d
--- /dev/null
+++ b/flang/test/Lower/percent-val-actual-argument.f90
@@ -0,0 +1,14 @@
+! RUN: bbc %s -emit-fir -o - | FileCheck %s
+
+program main
+ logical::a1
+ data a1/.true./
+ call sa(%val(a1))
+! CHECK: fir.load %3 : !fir.ref<!fir.logical<4>>
+! CHECK: fir.convert %13 : (!fir.logical<4>) -> i1
+ write(6,*) "a1 = ", a1
+end program main
+
+subroutine sa(x1)
+ logical::x1
+end subroutine sa
More information about the flang-commits
mailing list