Skip to content

Commit 09c544e

Browse files
authored
[flang] Do not propagate BIND(C) from main entry to ENTRY (#67554)
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.
1 parent 5aa3338 commit 09c544e

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

flang/lib/Evaluate/characteristics.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,9 +681,12 @@ static std::optional<Procedure> CharacterizeProcedure(
681681
},
682682
symbol.details())};
683683
if (result && !symbol.has<semantics::ProcBindingDetails>()) {
684-
CopyAttrs<Procedure, Procedure::Attr>(DEREF(GetMainEntry(&symbol)), *result,
684+
CopyAttrs<Procedure, Procedure::Attr>(symbol, *result,
685685
{
686686
{semantics::Attr::BIND_C, Procedure::Attr::BindC},
687+
});
688+
CopyAttrs<Procedure, Procedure::Attr>(DEREF(GetMainEntry(&symbol)), *result,
689+
{
687690
{semantics::Attr::ELEMENTAL, Procedure::Attr::Elemental},
688691
});
689692
if (IsPureProcedure(symbol) || // works for ENTRY too
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
! Test that lowering can handle entry statements with character
2+
! results where some entries are BIND(C) and not the others.
3+
! RUN: bbc -emit-hlfir %s -o - | FileCheck %s
4+
5+
function foo() bind(c)
6+
character(1) :: foo, bar
7+
entry bar()
8+
bar = "a"
9+
end function
10+
11+
! CHECK-LABEL: func.func @foo() -> !fir.char<1>
12+
! CHECK: %[[VAL_0:.*]] = arith.constant 1 : index
13+
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.char<1> {bindc_name = "foo", uniq_name = "_QFfooEfoo"}
14+
! 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>>)
15+
! CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
16+
! 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>>)
17+
! CHECK: cf.br ^bb1
18+
! CHECK: ^bb1:
19+
! CHECK: hlfir.assign %{{.*}} to %[[VAL_4]]#0 : !fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>
20+
! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_2]]#1 : !fir.ref<!fir.char<1>>
21+
! CHECK: return %[[VAL_8]] : !fir.char<1>
22+
! CHECK: }
23+
!
24+
! CHECK-LABEL: func.func @_QPbar(
25+
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.char<1>>,
26+
! CHECK-SAME: %[[VAL_1:.*]]: index) -> !fir.boxchar<1> {
27+
! CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<!fir.char<1,?>>
28+
! CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
29+
! 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,?>>)
30+
! CHECK: %[[VAL_5:.*]] = arith.constant 1 : index
31+
! 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,?>>)
32+
! CHECK: cf.br ^bb1
33+
! CHECK: ^bb1:
34+
! CHECK: hlfir.assign %{{.*}} to %[[VAL_6]]#0 : !fir.ref<!fir.char<1>>, !fir.boxchar<1>
35+
! CHECK: %[[VAL_10:.*]] = fir.emboxchar %[[VAL_6]]#1, %[[VAL_5]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
36+
! CHECK: return %[[VAL_10]] : !fir.boxchar<1>
37+
! CHECK: }
38+
39+
function foo2()
40+
character(1) :: foo2, bar2
41+
entry bar2() bind(c)
42+
bar2 = "a"
43+
end function
44+
! CHECK-LABEL: func.func @_QPfoo2(
45+
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.char<1>>,
46+
! CHECK-SAME: %[[VAL_1:.*]]: index) -> !fir.boxchar<1> {
47+
! CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<!fir.char<1,?>>
48+
! CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
49+
! 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,?>>)
50+
! CHECK: %[[VAL_5:.*]] = arith.constant 1 : index
51+
! 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,?>>)
52+
! CHECK: cf.br ^bb1
53+
! CHECK: ^bb1:
54+
! CHECK: hlfir.assign %{{.*}} to %[[VAL_6]]#0 : !fir.ref<!fir.char<1>>, !fir.boxchar<1>
55+
! CHECK: %[[VAL_10:.*]] = fir.emboxchar %[[VAL_4]]#1, %[[VAL_3]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
56+
! CHECK: return %[[VAL_10]] : !fir.boxchar<1>
57+
! CHECK: }
58+
59+
! CHECK-LABEL: func.func @bar2() -> !fir.char<1>
60+
! CHECK: %[[VAL_0:.*]] = arith.constant 1 : index
61+
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.char<1> {bindc_name = "foo2", uniq_name = "_QFfoo2Efoo2"}
62+
! 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>>)
63+
! CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
64+
! 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>>)
65+
! CHECK: cf.br ^bb1
66+
! CHECK: ^bb1:
67+
! CHECK: hlfir.assign %{{.*}} to %[[VAL_4]]#0 : !fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>
68+
! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_4]]#1 : !fir.ref<!fir.char<1>>
69+
! CHECK: return %[[VAL_8]] : !fir.char<1>
70+
! CHECK: }

0 commit comments

Comments
 (0)