Skip to content

Commit 8df115b

Browse files
committed
[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.
1 parent 2126a18 commit 8df115b

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

flang/lib/Lower/CallInterface.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ class Fortran::lower::CallInterfaceImpl {
702702
[&](const Fortran::evaluate::characteristics::DummyDataObject
703703
&dummy) {
704704
const auto &entity = getDataObjectEntity(std::get<1>(pair));
705-
if (dummy.CanBePassedViaImplicitInterface())
705+
if (!isBindC && dummy.CanBePassedViaImplicitInterface())
706706
handleImplicitDummy(&argCharacteristics, dummy, entity);
707707
else
708708
handleExplicitDummy(&argCharacteristics, dummy, entity,
@@ -871,7 +871,8 @@ class Fortran::lower::CallInterfaceImpl {
871871

872872
// Define when an explicit argument must be passed in a fir.box.
873873
bool dummyRequiresBox(
874-
const Fortran::evaluate::characteristics::DummyDataObject &obj) {
874+
const Fortran::evaluate::characteristics::DummyDataObject &obj,
875+
bool isBindC) {
875876
using ShapeAttr = Fortran::evaluate::characteristics::TypeAndShape::Attr;
876877
using ShapeAttrs = Fortran::evaluate::characteristics::TypeAndShape::Attrs;
877878
constexpr ShapeAttrs shapeRequiringBox = {
@@ -888,6 +889,8 @@ class Fortran::lower::CallInterfaceImpl {
888889
if (const Fortran::semantics::Scope *scope = derived->scope())
889890
// Need to pass length type parameters in fir.box if any.
890891
return scope->IsDerivedTypeWithLengthParameter();
892+
if (isBindC && obj.type.type().IsAssumedLengthCharacter())
893+
return true; // Fortran 2018 18.3.6 point 2 (5)
891894
return false;
892895
}
893896

@@ -973,7 +976,7 @@ class Fortran::lower::CallInterfaceImpl {
973976
addFirOperand(boxRefType, nextPassedArgPosition(), Property::MutableBox,
974977
attrs);
975978
addPassedArg(PassEntityBy::MutableBox, entity, characteristics);
976-
} else if (dummyRequiresBox(obj)) {
979+
} else if (dummyRequiresBox(obj, isBindC)) {
977980
// Pass as fir.box or fir.class
978981
if (isValueAttr)
979982
TODO(loc, "assumed shape dummy argument with VALUE attribute");
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
! Test that assumed length character scalars and explicit shape arrays are passed via
2+
! CFI descriptor (fir.box) in BIND(C) procedures. They are passed only by address
3+
! and length in non BIND(C) procedures. See Fortran 2018 standard 18.3.6 point 2(5).
4+
! RUN: bbc -emit-hlfir -o - %s 2>&1 | FileCheck %s
5+
6+
! CHECK: func.func @foo(
7+
! CHECK-SAME: %{{[^:]*}}: !fir.box<!fir.char<1,?>>
8+
! CHECK-SAME: %{{[^:]*}}: !fir.box<!fir.array<100x!fir.char<1,?>>>
9+
subroutine foo(c1, c3) bind(c)
10+
character(*) :: c1, c3(100)
11+
end subroutine
12+
13+
! CHECK: func.func @_QPnot_bindc(
14+
! CHECK-SAME: %{{[^:]*}}: !fir.boxchar<1>
15+
! CHECK-SAME: %{{[^:]*}}: !fir.boxchar<1>
16+
subroutine not_bindc(c1, c3)
17+
character(*) :: c1, c3(100)
18+
end subroutine

0 commit comments

Comments
 (0)