Skip to content

Commit

Permalink
[flang] Do not propagate BIND(C) from main entry to ENTRY (#67554)
Browse files Browse the repository at this point in the history
15.6.2.6 point 11/12/13 tells that entries do inherit the
RECURSIVE/PURE/ELEMENTAL aspects from the main entry, but nothing as
such is said for BIND(C). It seems each entry can independently have
BIND(C) or not.

Update characterization to not propagate this info in-between entries.

Add a lowering test for a tricky case of the character return where the
return ABI is different for the result with and without BIND(C), but the
results storage should be associated regardless of the ABI.
  • Loading branch information
jeanPerier committed Sep 27, 2023
1 parent 5aa3338 commit 09c544e
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
5 changes: 4 additions & 1 deletion flang/lib/Evaluate/characteristics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -681,9 +681,12 @@ static std::optional<Procedure> CharacterizeProcedure(
},
symbol.details())};
if (result && !symbol.has<semantics::ProcBindingDetails>()) {
CopyAttrs<Procedure, Procedure::Attr>(DEREF(GetMainEntry(&symbol)), *result,
CopyAttrs<Procedure, Procedure::Attr>(symbol, *result,
{
{semantics::Attr::BIND_C, Procedure::Attr::BindC},
});
CopyAttrs<Procedure, Procedure::Attr>(DEREF(GetMainEntry(&symbol)), *result,
{
{semantics::Attr::ELEMENTAL, Procedure::Attr::Elemental},
});
if (IsPureProcedure(symbol) || // works for ENTRY too
Expand Down
70 changes: 70 additions & 0 deletions flang/test/Lower/HLFIR/bindc-entry-stmt.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
! Test that lowering can handle entry statements with character
! results where some entries are BIND(C) and not the others.
! RUN: bbc -emit-hlfir %s -o - | FileCheck %s

function foo() bind(c)
character(1) :: foo, bar
entry bar()
bar = "a"
end function

! CHECK-LABEL: func.func @foo() -> !fir.char<1>
! CHECK: %[[VAL_0:.*]] = arith.constant 1 : index
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.char<1> {bindc_name = "foo", uniq_name = "_QFfooEfoo"}
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] typeparams %[[VAL_0]] {uniq_name = "_QFfooEfoo"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
! CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_2]]#1 typeparams %[[VAL_3]] {uniq_name = "_QFfooEbar"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
! CHECK: cf.br ^bb1
! CHECK: ^bb1:
! CHECK: hlfir.assign %{{.*}} to %[[VAL_4]]#0 : !fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>
! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_2]]#1 : !fir.ref<!fir.char<1>>
! CHECK: return %[[VAL_8]] : !fir.char<1>
! CHECK: }
!
! CHECK-LABEL: func.func @_QPbar(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.char<1>>,
! CHECK-SAME: %[[VAL_1:.*]]: index) -> !fir.boxchar<1> {
! CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<!fir.char<1,?>>
! CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %[[VAL_3]] {uniq_name = "_QFfooEfoo"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
! CHECK: %[[VAL_5:.*]] = arith.constant 1 : index
! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %[[VAL_5]] {uniq_name = "_QFfooEbar"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
! CHECK: cf.br ^bb1
! CHECK: ^bb1:
! CHECK: hlfir.assign %{{.*}} to %[[VAL_6]]#0 : !fir.ref<!fir.char<1>>, !fir.boxchar<1>
! CHECK: %[[VAL_10:.*]] = fir.emboxchar %[[VAL_6]]#1, %[[VAL_5]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
! CHECK: return %[[VAL_10]] : !fir.boxchar<1>
! CHECK: }

function foo2()
character(1) :: foo2, bar2
entry bar2() bind(c)
bar2 = "a"
end function
! CHECK-LABEL: func.func @_QPfoo2(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.char<1>>,
! CHECK-SAME: %[[VAL_1:.*]]: index) -> !fir.boxchar<1> {
! CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<!fir.char<1,?>>
! CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %[[VAL_3]] {uniq_name = "_QFfoo2Efoo2"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
! CHECK: %[[VAL_5:.*]] = arith.constant 1 : index
! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %[[VAL_5]] {uniq_name = "_QFfoo2Ebar2"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
! CHECK: cf.br ^bb1
! CHECK: ^bb1:
! CHECK: hlfir.assign %{{.*}} to %[[VAL_6]]#0 : !fir.ref<!fir.char<1>>, !fir.boxchar<1>
! CHECK: %[[VAL_10:.*]] = fir.emboxchar %[[VAL_4]]#1, %[[VAL_3]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
! CHECK: return %[[VAL_10]] : !fir.boxchar<1>
! CHECK: }

! CHECK-LABEL: func.func @bar2() -> !fir.char<1>
! CHECK: %[[VAL_0:.*]] = arith.constant 1 : index
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.char<1> {bindc_name = "foo2", uniq_name = "_QFfoo2Efoo2"}
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] typeparams %[[VAL_0]] {uniq_name = "_QFfoo2Efoo2"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
! CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_2]]#1 typeparams %[[VAL_3]] {uniq_name = "_QFfoo2Ebar2"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
! CHECK: cf.br ^bb1
! CHECK: ^bb1:
! CHECK: hlfir.assign %{{.*}} to %[[VAL_4]]#0 : !fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>
! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_4]]#1 : !fir.ref<!fir.char<1>>
! CHECK: return %[[VAL_8]] : !fir.char<1>
! CHECK: }

0 comments on commit 09c544e

Please sign in to comment.