[flang-commits] [flang] [flang] Do not propagate BIND(C) from main entry to ENTRY (PR #67554)
via flang-commits
flang-commits at lists.llvm.org
Wed Sep 27 06:27:15 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/67554.diff
2 Files Affected:
- (modified) flang/lib/Evaluate/characteristics.cpp (+4-1)
- (added) flang/test/Lower/HLFIR/bindc-entry-stmt.f90 (+70)
``````````diff
diff --git a/flang/lib/Evaluate/characteristics.cpp b/flang/lib/Evaluate/characteristics.cpp
index 6daa113abe64255..ac61e72f428a97e 100644
--- a/flang/lib/Evaluate/characteristics.cpp
+++ b/flang/lib/Evaluate/characteristics.cpp
@@ -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
diff --git a/flang/test/Lower/HLFIR/bindc-entry-stmt.f90 b/flang/test/Lower/HLFIR/bindc-entry-stmt.f90
new file mode 100644
index 000000000000000..89e494689e99642
--- /dev/null
+++ b/flang/test/Lower/HLFIR/bindc-entry-stmt.f90
@@ -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: }
``````````
</details>
https://github.com/llvm/llvm-project/pull/67554
More information about the flang-commits
mailing list