[flang] Check for BIND(C) through use association.
authorSlava Zakharin <szakharin@nvidia.com>
Wed, 1 Mar 2023 16:42:22 +0000 (08:42 -0800)
committerSlava Zakharin <szakharin@nvidia.com>
Wed, 1 Mar 2023 20:02:30 +0000 (12:02 -0800)
If the interface specifies BIND(C), then the declarations using
this interface inherit BIND(C), and if they are referenced via use
association they must be classified as BIND(C) subprograms.

Differential Revision: https://reviews.llvm.org/D145084

flang/lib/Semantics/tools.cpp
flang/test/Lower/bindc_procs.f90 [new file with mode: 0644]

index 4bed8a0..41a5ac2 100644 (file)
@@ -278,7 +278,8 @@ bool IsPointerDummy(const Symbol &symbol) {
   return IsPointer(symbol) && IsDummy(symbol);
 }
 
-bool IsBindCProcedure(const Symbol &symbol) {
+bool IsBindCProcedure(const Symbol &original) {
+  const Symbol &symbol{original.GetUltimate()};
   if (const auto *procDetails{symbol.detailsIf<ProcEntityDetails>()}) {
     if (procDetails->procInterface()) {
       // procedure component with a BIND(C) interface
diff --git a/flang/test/Lower/bindc_procs.f90 b/flang/test/Lower/bindc_procs.f90
new file mode 100644 (file)
index 0000000..514f771
--- /dev/null
@@ -0,0 +1,56 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+! CHECK-DAG: func.func private @proc1() attributes {fir.bindc_name = "proc1"}
+module decl1
+  interface
+     subroutine proc_iface() bind(C)
+     end subroutine proc_iface
+  end interface
+  procedure (proc_iface) PrOc1
+end module decl1
+subroutine test1(x)
+  use decl1
+  call PrOc1
+end subroutine test1
+
+! CHECK-DAG: func.func private @proc2() attributes {fir.bindc_name = "proc2"}
+module decl2
+  interface
+     subroutine proc_iface() bind(C)
+     end subroutine proc_iface
+  end interface
+end module decl2
+subroutine test2(x)
+  use decl2
+  procedure (proc_iface) PrOc2
+  call PrOc2
+end subroutine test2
+
+! CHECK-DAG: func.func private @func3() -> f32 attributes {fir.bindc_name = "func3"}
+module decl3
+  interface
+     real function func_iface() bind(C)
+     end function func_iface
+  end interface
+  procedure (func_iface) FuNc3
+end module decl3
+subroutine test3(x)
+  use decl3
+  real :: x
+  x = FuNc3()
+end subroutine test3
+
+! CHECK-DAG: func.func private @func4() -> f32 attributes {fir.bindc_name = "func4"}
+module decl4
+  interface
+     real function func_iface() bind(C)
+     end function func_iface
+  end interface
+end module decl4
+subroutine test4(x)
+  use decl4
+  procedure (func_iface) FuNc4
+  real :: x
+  x = FuNc4()
+end subroutine test4
+