Weird Preprocessor Bug in PGI 19.10


Recently, we’ve tried to re-up our PGI support for the model I work on, working on trying to fix/workaround F2003/2008 features we use that PGI doesn’t quite support yet. However, in doing so we encountered a rather odd bug. We eventually figured out that the column a pre-processor macro starts in, can sometimes cause an issue.

To wit, I present a stripped down code that has a waterfall of _ASSERT():

#    define __return return
#    define __rc(rc) ,rc

#define _FILE_ __FILE__

#    define _ASSERT_MSG_AND_LOC_AND_RC(A,msg,file,line,rc) if(MAPL_Assert(A,msg,file,line __rc(rc)))__return
#    define _ASSERT_MSG_AND_LOC(A,msg,file,line) _ASSERT_MSG_AND_LOC_AND_RC(A,msg,file,line,rc)
#    define _ASSERT(A,msg) _ASSERT_MSG_AND_LOC(A,msg,_FILE_,__LINE__)

subroutine MAPL_FieldAllocCommit(rc)
end subroutine MAPL_FieldAllocCommit

If you now run this through pgfortran:

(1054) $ pgfortran -V

pgfortran 19.10-0 LLVM 64-bit target on x86-64 Linux -tp skylake 
PGI Compilers and Tools
Copyright (c) 2019, NVIDIA CORPORATION.  All rights reserved.
(1055) $ pgfortran test.F90 -E
# 1 "test.F90"
# 11 "test.F90"
subroutine MAPL_FieldAllocCommit(rc)
if(MAPL_Assert(.false.,"column=1","test.F90",12 ,rc))return
 if(MAPL_Assert(.false.,"column=2","test.F90",13 ,rc))return
  if(MAPL_Assert(.false.,"column=3","test.F90",14 ,rc))return
   if(MAPL_Assert(.false.,"column=4","test.F90",15 ,rc))return
    if(MAPL_Assert(.false.,"column=5","test.F90",16 ,rc))return
     if(MAPL_Assert(.false.,"column=6","test.F90",17 ,rc))return
      if(MAPL_Assert(.false.,"column=7","test.F90",18 ,rc))return
       if(MAPL_Assert(.false.,"column=8","test.F90",19 ,rc))return
        if(MAPL_Assert(.false.,"column=9","test.F90",20 ,rc))return
         if(MAPL_Assert(.false.,"column=10","test.F90",21 ,rc))return
          if(MAPL_Assert(.false.,"column=11","test.F90",22 ,rc))return
           if(MAPL_Assert(.false.,"column=12","test.F90",23 ,rc))return
            if(MAPL_Assert(.false.,"column=13","test.F90",24 ,rc))return
             if(MAPL_Assert(.false.,"column=14","test.F90",25 ,rc))return
               if(MAPL_Assert(.false.,"column=16","test.F90",27 ,rc))return
                if(MAPL_Assert(.false.,"column=17","test.F90",28 ,rc))return
                  if(MAPL_Assert(.false.,"column=19","test.F90",30 ,rc))return
                   if(MAPL_Assert(.false.,"column=20","test.F90",31 ,rc))return
                    if(MAPL_Assert(.false.,"column=21","test.F90",32 ,rc))return
                     if(MAPL_Assert(.false.,"column=22","test.F90",33 ,rc))return
                      if(MAPL_Assert(.false.,"column=23","test.F90",34 ,rc))return
                       if(MAPL_Assert(.false.,"column=24","test.F90",35 ,rc))return
                        if(MAPL_Assert(.false.,"column=25","test.F90",36 ,rc))return
                         if(MAPL_Assert(.false.,"column=26","test.F90",37 ,rc))return
                          if(MAPL_Assert(.false.,"column=27","test.F90",38 ,rc))return
end subroutine MAPL_FieldAllocCommit

So if our macro starts in column 15 or 18, it doesn’t resolve correctly. You can see that _ASSERT() is a rather complex, nested macro but not horrible. Intel and GNU (and thus cpp) seem okay with this macro.

Now, I fiddled around and if you run with

pgfortran test.F90 -Mcpp=line -E

you don’t get the above issue. But since I don’t think you can use -Mcpp in combination with compilation, doesn’t really help us.

Any ideas?

Hi Ron,

This is a weird one. I suspect there’s probably a problem with an internal buffer in the preprocessor but not really sure. Will need a compiler engineer to investigate so I added a problem report, TPR #28009.

I don’t really have any good ideas for work arounds, other than to not start this macro in columns 15 or 17 or use a different preprocessor like cpp.

But since I don’t think you can use -Mcpp in combination with compilation, doesn’t really help us.

Correct, but if you can change your build to a two-step process, it should work.

pgfortran pre.F90 -Mcpp -o pre.f90 
pgfortran -c pre.f90