[PATCH] PR fortran/88227 -- Revenge of the BOZ

Steve Kargl sgk@troutmask.apl.washington.edu
Sun Jul 28 23:41:00 GMT 2019


The attach patch fixes a problem with the conversion of a
BOZ literal constant to a REAL where the size of the REAL
exceeds the size of the largest INTEGER.  The problem can
be seen on 32-bit targets that provide support for REAL(10)
and/or REAL(16), or it can be seen with a multilib target
when using -m32 and REAL(10) and/or REAL(16).

If needed, the patch converts an octal or hexidecimal string
to the equivalent binary string, and then converts the binary
string to a REAL.  In principle, bin2real() can convert to 
REAL(4), REAL(8), REAL(10), and REAL(16), but I have elected
to use the old conversion method if the size of the largest
INTEGER exceeds the size the REAL(XXX) of interest.  A future
patch may remove the old method and make this new approach the
only way to convert a BOZ.

I have attached a short test program.  There is no testcase
for testsuite.

PLEASE TEST.

2019-07-28  Steven G. Kargl  <kargl@gcc.gnu.org>

	PR fortran/88227
	* check.c (oct2bin):  New function.  Convert octal string to binary.
	(hex2bin): New function.  Convert hexidecimal string to binary.
	(bin2real): New function.  Convert binary string to REAL.  Use
	oct2bin and hex2bin.
	(gfc_boz2real):  Use fallback conversion bin2real.

-- 
Steve
-------------- next part --------------
A non-text attachment was scrubbed...
Name: boz_real10.diff
Type: text/x-diff
Size: 5247 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20190728/b1fe8421/attachment.bin>
-------------- next part --------------
subroutine foo10

   implicit none

   real(10) b, o, z, x

   b = real(b'010000000000000011001001000011111101101010100010001000010110100&
   &01100000000000000', 10)
   o = real(o'100001444176652104132140000', 10);
   z = real(z'4000C90FDAA22168C000', 10)
   print '(G0/,G0/,G0)', b, o, z

   b = real(b'011111111111111110000000000000000000000000000000000000000000000&
   &00000000000000000', 10)
   o = real(o'177777000000000000000000000', 10)
   z = real(z'7FFF8000000000000000', 10)
   print '(3(G0,1X))', b, o, z

   b = real(b'111111111111111110000000000000000000000000000000000000000000000&
   &00000000000000000', 10)
   o = real(o'377777000000000000000000000', 10)
   z = real(z'FFFF8000000000000000', 10)
   print '(3(G0,1X))', b, o, z

   b = real(b'111111111111111111000000000000000000000000000000000000000000000&
   &00000000000000000', 10)
   o = real(o'377777400000000000000000000', 10)
   z = real(z'FFFFC000000000000000', 10)
   print '(3(G0,1X))', b, o, z

   b = real(b'011111111111111111000000000000000000000000000000000000000000000&
   &00000000000000000', 10)
   o = real(o'177777400000000000000000000', 10)
   z = real(z'7FFFC000000000000000', 10)
   print '(3(G0,1X))', b, o, z

end subroutine foo10

subroutine foo16

   implicit none

   real(16) b, o, z, x

   b = real(b'010000000000000010010010000111111011010101000100010000101101000&
   &11000010001101001100010011000110011000101000101110000000110111000', 16)
   o = real(o'1000011103755242102643021514230630505600670', 16);
   z = real(z'4000921FB54442D18469898CC51701B8', 16)
   print '(G0/,G0/,G0)', b, o, z

   b = real(b'011111111111111100000000000000000000000000000000000000000000000&
   &00000000000000000000000000000000000000000000000000000000000000000', 16)
   o = real(o'1777760000000000000000000000000000000000000', 16)
   z = real(z'7FFF0000000000000000000000000000', 16)
   print '(3(G0,1X))', b, o, z

   b = real(b'111111111111111100000000000000000000000000000000000000000000000&
   &00000000000000000000000000000000000000000000000000000000000000000', 16)
   o = real(o'3777760000000000000000000000000000000000000', 16)
   z = real(z'FFFF0000000000000000000000000000', 16)
   print '(3(G0,1X))', b, o, z

   b = real(b'111111111111111110000000000000000000000000000000000000000000000&
   &00000000000000000000000000000000000000000000000000000000000000000', 16)
   o = real(o'3777770000000000000000000000000000000000000', 16)
   z = real(z'FFFF8000000000000000000000000000', 16)
   print '(3(G0,1X))', b, o, z

   b = real(b'011111111111111110000000000000000000000000000000000000000000000&
   &00000000000000000000000000000000000000000000000000000000000000000', 16)
   o = real(o'1777770000000000000000000000000000000000000', 16)
   z = real(z'7FFF8000000000000000000000000000', 16)
   print '(3(G0,1X))', b, o, z

end subroutine foo16

program foo
   call foo10
   print *
   call foo16
end program foo


More information about the Fortran mailing list