[flang-commits] [flang] a96b467 - [flang] Lower BIND(C) module variables (#78279)

via flang-commits flang-commits at lists.llvm.org
Wed Jan 17 08:44:43 PST 2024


Author: jeanPerier
Date: 2024-01-17T17:44:39+01:00
New Revision: a96b4671b97b167230986bd2811676064c608596

URL: https://github.com/llvm/llvm-project/commit/a96b4671b97b167230986bd2811676064c608596
DIFF: https://github.com/llvm/llvm-project/commit/a96b4671b97b167230986bd2811676064c608596.diff

LOG: [flang] Lower BIND(C) module variables (#78279)

Lower initialized BIND(C) module variable as regular module variable,
except that the fir.global symbol name is the binding label.

For uninitialized variables, add the common linkage so that C code may
define the variables. The standard does not provide a way to indicate
that a variable is defined in C, but there are use cases.

Beware that if the module file compiled object is added to a shared
library, the variable will become a regular global definition and may
override the C variable depending on the linking order.

Added: 
    flang/test/Lower/HLFIR/bindc-module-var.f90

Modified: 
    flang/lib/Lower/ConvertVariable.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index ad44de71ee828a8..dd024a0a1ec7927 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -595,14 +595,17 @@ static fir::GlobalOp defineGlobal(Fortran::lower::AbstractConverter &converter,
   // Creates zero initializer for globals without initializers, this is a common
   // and expected behavior (although not required by the standard)
   if (!globalIsInitialized(global)) {
-    // TODO: For BIND(C) variables, an initial value may be given in another
-    // compilation unit (on the C side), and setting an zero init here creates
-    // linkage conflicts. See if there is a way to get it zero initialized if
-    // not initialized elsewhere. MLIR also used to drop globals without
-    // initializers that are not used in the file, but this may not be true
-    // anymore.
+    // Fortran does not provide means to specify that a BIND(C) module
+    // uninitialized variables will be defined in C.
+    // Add the common linkage to those to allow some level of support
+    // for this use case. Note that this use case will not work if the Fortran
+    // module code is placed in a shared library since, at least for the ELF
+    // format, common symbols are assigned a section in shared libraries.
+    // The best is still to declare C defined variables in a Fortran module file
+    // with no other definitions, and to never link the resulting module object
+    // file.
     if (sym.attrs().test(Fortran::semantics::Attr::BIND_C))
-      TODO(loc, "BIND(C) module variable linkage");
+      global.setLinkName(builder.createCommonLinkage());
     Fortran::lower::createGlobalInitialization(
         builder, global, [&](fir::FirOpBuilder &builder) {
           mlir::Value initValue = builder.create<fir::ZeroOp>(loc, symTy);

diff  --git a/flang/test/Lower/HLFIR/bindc-module-var.f90 b/flang/test/Lower/HLFIR/bindc-module-var.f90
new file mode 100644
index 000000000000000..20848078b3eba31
--- /dev/null
+++ b/flang/test/Lower/HLFIR/bindc-module-var.f90
@@ -0,0 +1,29 @@
+! Test BIND(C) module variable lowering
+! RUN: bbc -emit-hlfir -o - %s | FileCheck %s
+
+module some_c_module
+  integer, bind(c, name="i_var") :: i = 1
+  integer, bind(c, name="i_var_no_init") :: i_no_init
+  integer, bind(c) :: j_var = 2
+  integer, bind(c) :: j_var_no_init
+end module
+
+! CHECK-LABEL:   fir.global @i_var : i32 {
+! CHECK:           %[[VAL_0:.*]] = arith.constant 1 : i32
+! CHECK:           fir.has_value %[[VAL_0]] : i32
+! CHECK:         }
+
+! CHECK-LABEL:   fir.global common @i_var_no_init : i32 {
+! CHECK:           %[[VAL_0:.*]] = fir.zero_bits i32
+! CHECK:           fir.has_value %[[VAL_0]] : i32
+! CHECK:         }
+
+! CHECK-LABEL:   fir.global @j_var : i32 {
+! CHECK:           %[[VAL_0:.*]] = arith.constant 2 : i32
+! CHECK:           fir.has_value %[[VAL_0]] : i32
+! CHECK:         }
+
+! CHECK-LABEL:   fir.global common @j_var_no_init : i32 {
+! CHECK:           %[[VAL_0:.*]] = fir.zero_bits i32
+! CHECK:           fir.has_value %[[VAL_0]] : i32
+! CHECK:         }


        


More information about the flang-commits mailing list