[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:25:37 PDT 2023


https://github.com/jeanPerier created https://github.com/llvm/llvm-project/pull/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.

>From 1ee77068e72cea35a926cb533f5fe3d4ed279fb6 Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Wed, 27 Sep 2023 06:17:37 -0700
Subject: [PATCH] [flang] Do not propagate BIND(C) from main entry to ENTRY

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.
---
 flang/lib/Evaluate/characteristics.cpp      |  5 +-
 flang/test/Lower/HLFIR/bindc-entry-stmt.f90 | 70 +++++++++++++++++++++
 2 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 flang/test/Lower/HLFIR/bindc-entry-stmt.f90

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:         }



More information about the flang-commits mailing list