Skip to content

[flang] handle common block used as BIND(C) module variables #145669

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 26, 2025

Conversation

jeanPerier
Copy link
Contributor

Support odd case where a static object is being declared both as a common block and a BIND(C) module variable name in different modules, and both modules are used in the same compilation unit.

This is not standard, but happens when using MPI and MPI_F08 in the same compilation unit, and at least both gfortran and ifx support this.

See added test case for an illustration.

Previously, this code triggered an HLFIR verification error: 'hlfir.declare' op of numeric, logical, or assumed type entity must not have length parameters

@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir labels Jun 25, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 25, 2025

@llvm/pr-subscribers-flang-fir-hlfir

Author: None (jeanPerier)

Changes

Support odd case where a static object is being declared both as a common block and a BIND(C) module variable name in different modules, and both modules are used in the same compilation unit.

This is not standard, but happens when using MPI and MPI_F08 in the same compilation unit, and at least both gfortran and ifx support this.

See added test case for an illustration.

Previously, this code triggered an HLFIR verification error: 'hlfir.declare' op of numeric, logical, or assumed type entity must not have length parameters


Full diff: https://github.com/llvm/llvm-project/pull/145669.diff

2 Files Affected:

  • (modified) flang/lib/Lower/ConvertVariable.cpp (+6-1)
  • (added) flang/test/Lower/variable-common-viewed-as-module-var.f90 (+37)
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index a28596bfd0099..6f818cd7dc303 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -687,8 +687,13 @@ static void instantiateGlobal(Fortran::lower::AbstractConverter &converter,
   }
   auto addrOf = builder.create<fir::AddrOfOp>(loc, global.resultType(),
                                               global.getSymbol());
+  // The type of the global cannot be trusted to be the same as the one
+  // of the variable as some existing programs map common blocks to
+  // BIND(C) module variables (e.g. mpi_argv_null in MPI and MPI_F08).
+  mlir::Type varAddrType = fir::ReferenceType::get(converter.genType(sym));
+  mlir::Value cast = builder.createConvert(loc, varAddrType, addrOf);
   Fortran::lower::StatementContext stmtCtx;
-  mapSymbolAttributes(converter, var, symMap, stmtCtx, addrOf);
+  mapSymbolAttributes(converter, var, symMap, stmtCtx, cast);
 }
 
 //===----------------------------------------------------------------===//
diff --git a/flang/test/Lower/variable-common-viewed-as-module-var.f90 b/flang/test/Lower/variable-common-viewed-as-module-var.f90
new file mode 100644
index 0000000000000..e303df6d91a98
--- /dev/null
+++ b/flang/test/Lower/variable-common-viewed-as-module-var.f90
@@ -0,0 +1,37 @@
+! RUN: bbc -emit-hlfir %s -o - | FileCheck %s
+
+! Test non standard definition of a common block as a BIND(C) variable.
+! This happens when MPI and MPI_F08 are used inside the same compilation
+! unit because MPI uses common blocks while MPI_F08 uses BIND(C) variables
+! to refer to the same objects (e.g. mpi_argv_null).
+
+module m_common_var
+ character(1) :: var
+ common /var_storage/var
+end module
+
+module m_bindc_var
+  character(1), bind(c, name="var_storage_") :: var
+end module
+
+subroutine s1()
+  use m_common_var, only : var
+  var = "a"
+end subroutine
+
+subroutine s2()
+  use m_bindc_var, only : var
+  print *, var
+end subroutine
+
+  call s1()
+  call s2()
+end
+
+! CHECK: fir.global common @var_storage_(dense<0> : vector<1xi8>) {alignment = 1 : i64} : !fir.array<1xi8>
+
+! CHECK-LABEL: func.func @_QPs1
+! CHECK: hlfir.declare %{{.*}} typeparams %c1 {uniq_name = "_QMm_common_varEvar"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)
+
+! CHECK-LABEL: func.func @_QPs2
+! CHECK: hlfir.declare %{{.*}} typeparams %c1 {fortran_attrs = #fir.var_attrs<bind_c>, uniq_name = "var_storage_"} : (!fir.ref<!fir.char<1>>, index) -> (!fir.ref<!fir.char<1>>, !fir.ref<!fir.char<1>>)

@jeanPerier jeanPerier merged commit 13daf65 into llvm:main Jun 26, 2025
10 checks passed
anthonyhatran pushed a commit to anthonyhatran/llvm-project that referenced this pull request Jun 26, 2025
…5669)

Support odd case where a static object is being declared both as a
common block and a BIND(C) module variable name in different modules,
and both modules are used in the same compilation unit.

This is not standard, but happens when using MPI and MPI_F08 in the same
compilation unit, and at least both gfortran and ifx support this.

See added test case for an illustration.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants