This is the mail archive of the
mailing list for the GCC project.
Re: [Committed] PR fortran/54072 -- More fun with BOZ
On Thu, Aug 08, 2019 at 09:31:37AM +0100, Mark Eggleston wrote:
> On 07/08/2019 19:56, Steve Kargl wrote:
> > On Wed, Aug 07, 2019 at 09:09:49AM -0700, Steve Kargl wrote:
> >> On Wed, Aug 07, 2019 at 01:58:17PM +0100, Mark Eggleston wrote:
> >>> DATA statements for logical and character variable compile but do not work:
> >>> program test
> >>> character(4) :: c
> >>> data c / z'41424344' /
> >>> write(*, *) "'" // c // "'", transfer(c, 0_4)
> >>> end program test
> >>> Outputs:
> >>> '' 0
> > Prior versions of gfortran give
> > % gfc9 -c a.f90
> > a.f90:3:10:
> > 3 | data c / z'41424344' /
> > | 1
> > Error: Incompatible types in DATA statement at (1); attempted conversion of INTEGER(16) to CHARACTER(1)
> > I have a patch that now does
> > gfcx -c a.f90
> > a.f90:3:10-23:
> > 3 | data c / z'41424344' /
> > | 1 2
> > Error: data-stmt-object at (1) has type 'CHARACTER', which conflicts with the BOZ literal constant at (2)
> Is there any particular reason for reverting to the earlier behaviour
> instead of fixing the contents of c?
> "C4102 (R463) A boz-literal-constant shall appear only as a
> data-stmt-constant in a DATA statement, or where explicitly allowed in
> subclause 13.7 as an actual argument of an intrinsic procedure." from
> the 2008 standard implies that the use of a BOZ in the data statement of
> a character variable is allowed, it doesn't say that it is restricted to
> numeric types.
You're looking at the wrong part of the Fortran standard,
and yes, I know it can sometimes be hard to find the right
Fortran working document, page. 111.
If a data-stmt-constant is a boz-literal-constant, the corresponding
variable shall be of type integer.
You should be able to find some version of this sentence in all version
of the Fortran standard starting with Fortran 95. As an extension,
gfortran allows a data-stmt-object to also have a type real.
> > BTW, -fallow-invalid-boz does enable all previous broken
> > usages of BOZ.
Whoops. That sentences has been munged. It should have read
BTW, -fallow-invalid-boz does NOT enable all previous broken
usages of BOZ.
The missing NOT certainly changed the intent. Again, historically
a BOZ was converted to an INTEGER(16) right after the BOZ was parsed.
This allowed a BOZ to appear anywhere an INTEGER(16) could appear.
There was an is_boz sentinel in the gfc_expr structure, but it was
only used in a few places.
Consider this piece of code
% cat a.f90
print *, abs(z'4049abdf')
% gfortran8 -o z a.f90 && ./z
In F2008 and later, a BOZ is a typeless string of bits without a
kind type parameter. ABS() is a generic function. Which specific
should be called? It cannot be determined from the argument. Now,
% gfcx -c a.f90
1 | print *, abs(z'4049abdf')
Error: 'a' argument of 'abs' intrinsic at (1) must have a numeric type
> In that case comparisons with BOZ should be allowed but they are not as
> indicated in my previous e-mail
BOZ are not allowed as an operand in an expression. If you have
code that does
if (i .eq. z'1234') ...
The correct way to write this is
if (i .eq. int(z'1234')) ...
I thought about introducing -fbroken-boz option where the
gfortran source code would have had code that looked like
old implementation used in gfortran 9 and older
There were two problems with this. First, it would become a
maintenance nightmare of unmanagable code. Second, users
would simply set -fbroken-boz as a default option and never
fix their codes, which then means the dual implementations
would both need to maintained forever.