[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