Skip to content

Commit 13daf65

Browse files
authored
[flang] handle common block used as BIND(C) module variables (#145669)
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.
1 parent a226542 commit 13daf65

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

flang/lib/Lower/ConvertVariable.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,8 +687,13 @@ static void instantiateGlobal(Fortran::lower::AbstractConverter &converter,
687687
}
688688
auto addrOf = builder.create<fir::AddrOfOp>(loc, global.resultType(),
689689
global.getSymbol());
690+
// The type of the global cannot be trusted to be the same as the one
691+
// of the variable as some existing programs map common blocks to
692+
// BIND(C) module variables (e.g. mpi_argv_null in MPI and MPI_F08).
693+
mlir::Type varAddrType = fir::ReferenceType::get(converter.genType(sym));
694+
mlir::Value cast = builder.createConvert(loc, varAddrType, addrOf);
690695
Fortran::lower::StatementContext stmtCtx;
691-
mapSymbolAttributes(converter, var, symMap, stmtCtx, addrOf);
696+
mapSymbolAttributes(converter, var, symMap, stmtCtx, cast);
692697
}
693698

694699
//===----------------------------------------------------------------===//
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
! RUN: bbc -emit-hlfir %s -o - | FileCheck %s
2+
3+
! Test non standard definition of a common block as a BIND(C) variable.
4+
! This happens when MPI and MPI_F08 are used inside the same compilation
5+
! unit because MPI uses common blocks while MPI_F08 uses BIND(C) variables
6+
! to refer to the same objects (e.g. mpi_argv_null).
7+
8+
module m_common_var
9+
character(1) :: var
10+
common /var_storage/var
11+
end module
12+
13+
module m_bindc_var
14+
character(1), bind(c, name="var_storage_") :: var
15+
end module
16+
17+
subroutine s1()
18+
use m_common_var, only : var
19+
var = "a"
20+
end subroutine
21+
22+
subroutine s2()
23+
use m_bindc_var, only : var
24+
print *, var
25+
end subroutine
26+
27+
call s1()
28+
call s2()
29+
end
30+
31+
! CHECK: fir.global common @var_storage_(dense<0> : vector<1xi8>) {alignment = 1 : i64} : !fir.array<1xi8>
32+
33+
! CHECK-LABEL: func.func @_QPs1
34+
! 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>>)
35+
36+
! CHECK-LABEL: func.func @_QPs2
37+
! 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>>)

0 commit comments

Comments
 (0)