Clarification on BGE and BOZ literal constants

Anyone disagree that the two values marked “wrong” returned by gfortran 10.3.0 are wrong?
Getting ready to file a bug report if agreed (have not tested with newer versions yet, though).

My conjecture in the following code is all returned values from BGE()
should be .true. except for the oversized value which it would be nice
to get a warning for, if not an error.

ifort 2021.3.0 20210609 produces the answers I expect, but gfortran
10.3.0. compiler does not. Results from any other compiler family would be appreciated.

    > 1000000000000000000000000000000000000000000000000000000000000000
    > 1
    >  T
    >  T
    >  T
    >  T
    >  T
    >  F  <-- wrong
    >  F  <-- wrong
    >  T
    >  T
    >  T
    >  F  <-- should not do, but would like warning

My read of the standard is that the shorter variable should have 0 bits
padded on the left till it is the length of the longer variable up to
the number of bits in the biggest bitsize any integer type has, but
gfortran seems to truncate the BOZ content to the rightmost number of
bits that matches the kind of any integer present, much like is done
with other bit-level routines that return numeric values (as opposed to
logical).

Fortran source
program demo_bge
use,intrinsic :: iso_fortran_env, only : int8, int16, int32, int64
implicit none
integer(kind=int8)  :: byte
integer(kind=int64) :: big
     
   big=-huge(big)-1
   byte=1
   write(*,'(b0)')big, byte
   ! ok with integers
   write(*,*)bge(big,1_int8)   ! T
   write(*,*)bge(big,1_int16)  ! T
   write(*,*)bge(big,1_int32)  ! T
   write(*,*)bge(big,1_int64)  ! T
     
   ! appears to be truncating BOZ literal constant number of bits
   ! of other argument(?)
   write(*,*)bge( b'10000000', byte)   ! T
   write(*,*)bge( b'100000000', byte)  ! T
   write(*,*)bge( b'100000000000000000000000000000000', 1)  ! T

   ! two constants
   ! not sure why you would want to, but does not appear prohibited
   write(*,*)bge( b'10000000',  b'00000001')  ! T
   write(*,*)bge( b'100000000', b'00000001')  ! T
   write(*,*)bge( b'10000000000000000000000000000000', b'00000001')  ! T

   ! any warning about size exceeded?
!$ ifndef INTEL
   write(*,*)bge( b'10000000000000000000000000000000000000000000000&
   &000000000000000000000000000000000000000000000000000000000000000&
   &000000000000000000000000000000000000000000000000000000000000000&
   &000000000000000000000000000000000000000000000000000000000000000&
   &000000000000000000000000000000000000000000000000000000000000000&
   &000000000000000000000000000000000000000000000000000000000000000&
   &000000000000000000000000000000000000000000000000000000000000000&
   &000000000000000000000000000000000000000000000000000000000000000&
   &000000000000000000000000000000000000000000000000000000000000000&
   &000000000000000000000000000000000000000000000000000000000000000&
   &000000000000000000000000000000000000000000000000000000000000000&
   &000000000000000000000000000000000000000000000000000000000000000&
   &000000000000000000000000000000000000000000000000000000000000000&
   &0000000000000000000000000000000000000000000000001', b'00000011')  ! T
!$endif
     
end program demo_bge

gfortran documentation says that in bge(i,j), j should be of the same kind as i, so, maybe some of those example are not legit?

Intel instead says that if the two kinds are different, the shortest one is padded with zeroes on the LEFT.

These are two different behaviors, but I have no clue what’s closest to what the standard says…

Might have changed in 2018. ifort says/does what I think 2018 standard indicates; have not gone back to see if that was a “recent” change in the standard.

This patch by @kargl exactly handles that. It seems like gfortran has the same option for all BOZ inputs to either truncate or pad them with zeros, to match an appropriate type.

The behavior you see is that apparently the integer kind in bge(b'something',j) is taken from j, instead of from a minimum-viable-representation of the boz input. That seems consistent with the assumption that boz is typeless → take kind from j → (in this case) trim value to int8. But, is that what should be expected as output from bge, or should instead the largest integer representation be taken? I don’t know.

I commented out the $ifndef and matching $endif preprocessor directives. I use a wrapper that compiles the code between the fortran and lines so I literally compiled the entire message before pasting it; and it still works for me extracted so I assume it is those directives causing you a problem (?). Not sure what error message you got.

This document reads:

When bit sequences of unequal length are compared, the shorter sequence is considered to extended by padding with zero bits on the left.

So perhaps yes, though properly documented, gfortran may not be complying with the standard here….