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
text.

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')
   end
% gfortran8 -o z a.f90  && ./z
           1078569951

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,
you get

% gfcx -c a.f90
a.f90:1:16:

    1 |    print *, abs(z'4049abdf')
      |                1
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 
> https://gcc.gnu.org/ml/fortran/2019-08/msg00031.html

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

   if (flag_broken_boz)
     {
       old implementation used in gfortran 9 and older
     }
   else
     {
       new implementation
     }

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.

-- 
Steve

Reply via email to