[flang-commits] [flang] [flang] Lower BIND(C) assumed length to CFI descriptor (PR #65950)
via flang-commits
flang-commits at lists.llvm.org
Mon Sep 11 05:05:28 PDT 2023
https://github.com/jeanPerier created https://github.com/llvm/llvm-project/pull/65950:
Outside of BIND(C), assumed length character scalar and explicit shape are passed by address + an extra length argument (fir.boxchar in FIR).
The standard mandates that they be passed via CFI descriptor in BIND(C) interface (fir.box in FIR). This patch fix the handling for this case.
>From c915a392722ca0afc5d10e30f8b6dd582817e0de Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Mon, 11 Sep 2023 04:51:57 -0700
Subject: [PATCH] [flang] Lower BIND(C) assumed length to CFI descriptor
Outside of BIND(C), assumed length character scalar and explicit shape
are passed by address + an extra length argument (fir.boxchar in FIR).
The standard mandates that they be passed via CFI descriptor in
BIND(C) interface (fir.box in FIR). This patch fix the handling for
this case.
---
flang/lib/Lower/CallInterface.cpp | 9 ++++++---
.../test/Lower/HLFIR/bindc-assumed-length.f90 | 18 ++++++++++++++++++
2 files changed, 24 insertions(+), 3 deletions(-)
create mode 100644 flang/test/Lower/HLFIR/bindc-assumed-length.f90
diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp
index 034bce4b13885c0..bc666532a545e52 100644
--- a/flang/lib/Lower/CallInterface.cpp
+++ b/flang/lib/Lower/CallInterface.cpp
@@ -702,7 +702,7 @@ class Fortran::lower::CallInterfaceImpl {
[&](const Fortran::evaluate::characteristics::DummyDataObject
&dummy) {
const auto &entity = getDataObjectEntity(std::get<1>(pair));
- if (dummy.CanBePassedViaImplicitInterface())
+ if (!isBindC && dummy.CanBePassedViaImplicitInterface())
handleImplicitDummy(&argCharacteristics, dummy, entity);
else
handleExplicitDummy(&argCharacteristics, dummy, entity,
@@ -871,7 +871,8 @@ class Fortran::lower::CallInterfaceImpl {
// Define when an explicit argument must be passed in a fir.box.
bool dummyRequiresBox(
- const Fortran::evaluate::characteristics::DummyDataObject &obj) {
+ const Fortran::evaluate::characteristics::DummyDataObject &obj,
+ bool isBindC) {
using ShapeAttr = Fortran::evaluate::characteristics::TypeAndShape::Attr;
using ShapeAttrs = Fortran::evaluate::characteristics::TypeAndShape::Attrs;
constexpr ShapeAttrs shapeRequiringBox = {
@@ -888,6 +889,8 @@ class Fortran::lower::CallInterfaceImpl {
if (const Fortran::semantics::Scope *scope = derived->scope())
// Need to pass length type parameters in fir.box if any.
return scope->IsDerivedTypeWithLengthParameter();
+ if (isBindC && obj.type.type().IsAssumedLengthCharacter())
+ return true; // Fortran 2018 18.3.6 point 2 (5)
return false;
}
@@ -973,7 +976,7 @@ class Fortran::lower::CallInterfaceImpl {
addFirOperand(boxRefType, nextPassedArgPosition(), Property::MutableBox,
attrs);
addPassedArg(PassEntityBy::MutableBox, entity, characteristics);
- } else if (dummyRequiresBox(obj)) {
+ } else if (dummyRequiresBox(obj, isBindC)) {
// Pass as fir.box or fir.class
if (isValueAttr)
TODO(loc, "assumed shape dummy argument with VALUE attribute");
diff --git a/flang/test/Lower/HLFIR/bindc-assumed-length.f90 b/flang/test/Lower/HLFIR/bindc-assumed-length.f90
new file mode 100644
index 000000000000000..14b9a2201cf1be8
--- /dev/null
+++ b/flang/test/Lower/HLFIR/bindc-assumed-length.f90
@@ -0,0 +1,18 @@
+! Test that assumed length character scalars and explicit shape arrays are passed via
+! CFI descriptor (fir.box) in BIND(C) procedures. They are passed only by address
+! and length in non BIND(C) procedures. See Fortran 2018 standard 18.3.6 point 2(5).
+! RUN: bbc -emit-hlfir -o - %s 2>&1 | FileCheck %s
+
+! CHECK: func.func @foo(
+! CHECK-SAME: %{{[^:]*}}: !fir.box<!fir.char<1,?>>
+! CHECK-SAME: %{{[^:]*}}: !fir.box<!fir.array<100x!fir.char<1,?>>>
+subroutine foo(c1, c3) bind(c)
+ character(*) :: c1, c3(100)
+end subroutine
+
+! CHECK: func.func @_QPnot_bindc(
+! CHECK-SAME: %{{[^:]*}}: !fir.boxchar<1>
+! CHECK-SAME: %{{[^:]*}}: !fir.boxchar<1>
+subroutine not_bindc(c1, c3)
+ character(*) :: c1, c3(100)
+end subroutine
More information about the flang-commits
mailing list