bind(c) variables optimized away

There appears to be a bug that the pgfortran compiler is optimizing away unused variables even when they are bind©:

> pgfortran -c test.f90
> pgcc main.c
/usr/bin/ld: /tmp/andy/pgccFUIeD6ja2FdJ.o: in function `main':
/home/andy/pgi/a/main.c:4: undefined reference to `global_var'



> gfortran -c test.f90
> gcc main.c test.o
> ./a.out
9



> cat test.f90
module m
 use iso_c_binding, only : c_int
 integer(c_int), bind(c) :: global_var=9
end module



> cat main.c
#include <stdio.h>
extern int global_var;
int main () {
 fprintf(stdout,"%d\n",global_var);
}



> pgfortran -V

pgfortran 20.4-0 LLVM 64-bit target on x86-64 Linux -tp nehalem
PGI Compilers and Tools
Copyright (c) 2020, NVIDIA CORPORATION.  All rights reserved.



> pgcc -V

pgcc (aka pgcc18) 20.4-0 LLVM 64-bit target on x86-64 Linux -tp nehalem
PGI Compilers and Tools
Copyright (c) 2020, NVIDIA CORPORATION.  All rights reserved.

Of course this is a highly unusual case in that the variable is not referenced at all from the Fortran.

Hi Andy,

It looks like you just forgot to add “test.o” to the link for the pgcc case.

% pgfortran -V20.4 -c test.f90
% pgcc -V20.4 main.c test.o
main.c:
% a.out
9

You get the same error GNU when test.o is missing.

% gfortran -c test.f90
% gcc main.c
/tmp/ccNfQxRT.o: In function `main':
main.c:(.text+0x6): undefined reference to `global_var'
collect2: error: ld returned 1 exit status

-Mat

Apologies, I made a mistake in haste to get a cut-down reproducer. This hopefully shows the issue:

> cat test.f90 
module m
 use iso_c_binding, only : c_int
 integer(c_int), bind(c) :: global_var
end module



> cat main.c 
extern int global_var;
int main () {
 global_var=9;
}



> pgfortran -c test.f90
> pgcc main.c test.o
main.c:
/usr/bin/ld: main.o: in function `main':
/home/andy/a/main.c:3: undefined reference to `global_var'



> gfortran -c test.f90
> gcc main.c test.o
>

Thanks, I’m able to recreate the problem and have filed TPR #28525. We’ll have our engineers take a look.

The obvious work around is to set the variable in the module to a default value.

-Mat