[Committed] PR fortran/54072 -- More fun with BOZ

Mark Eggleston mark.eggleston@codethink.co.uk
Thu Aug 8 09:41:00 GMT 2019


On 07/08/2019 17:09, Steve Kargl wrote:
> On Wed, Aug 07, 2019 at 01:58:17PM +0100, Mark Eggleston wrote:
>> BOZ problems in the following areas
>>
>>    * use of logical and character variables with BOZ constants
>>    * comparisons with BOZ constants
>>    * DATA statements
>>
>> Comparing 9.1 and trunk:
> The comparison is somewhat irrelevant.  I removed a
> a number of undocumented extensions when I made the
> handling of BOZ conform to the F2018 Fortran standard.
>
>> Comparisons with BOZ constants was allowed using 9.1 with
>> -Wconversion-extra:
>>
>>       5 |         if (i4 .eq. z'1000') then
>>         |            1
>> Warning: Conversion from INTEGER(4) to INTEGER(16) at (1)
>> [-Wconversion-extra]
> This is the old behavior were a BOZ upon parsing is
> immediately converted to an INTEGER with the widest decimal
> range.  It is a holdover from when I made BOZ work in
> accordance with the Fortran 95 standard, where a BOZ is
> only allowed as a data-stmt-constant.  On your target, that
> is INTEGER(16).  Because of that conversion, a BOZ could
> be used anywhere an INTEGER can be used.

Other invalid BOZ usage is enable with -fallow-invalid-box, why not this?

This is from a test suite for a customer to check that gfortran supports 
various legacy features. This feature is supported by all the compilers 
they use including gfortran up to 9.1. This change will break legacy 
code. Of course the best solution is to update their code i.e:

if (i4 .eq. int(z'1000',4)) then

I'll check whether the old behaviour is still required.

>
>> Using trunk  with -fallow-invalid-boz comparison is not allowed:
>>
>>       5 |         if (i4 .eq. z'1000') then
>>         |            1
>> Error: Operands of comparison operator '.eq.' at (1) are INTEGER(4)/BOZ
>>
>> I would have expected a suitable warning about using the BOZ in an
>> inappropriate place.
> A BOZ cannot be an operand to a binary operator.
>
> Consider
>
> x = 1.0 + z'40490fdb'   ! Is this 4.14159.... or 1.07853005E+09
>
> y = z'40490fdb' + z'40490fbd' + 1. ! Is this 2*pi+1 or 2.15...E+09.
>
> Note, gfortran does left-to-right evaluation, but Fortran standard
> does not require this ordering.  For 'x' it is possible to convert
> op2 to the type of op1, which would give 4.1415....  That behavior
> is different in comparison to the historical accident of 1.08E9.
> For 'y', there is no valid conversion of op1 into op2.  In older
> versions, the first addition is of 2 INTEGER(16).  The second
> addition converts a INTEGER(16) to a REAL(4) and then adds.
>
>> 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
>>
>> program test
>>     logical(4) b / z'00000001' /
>>     write(*, *) b
>> end program test
>>
>> Outputs:
>>
>>    F
>  From the current Fortran working documenti, page 111:
>
>     If a data-stmt-constant is a boz-literal-constant, the corresponding
>     variable shall be of type integer.  The boz-literal-constant is
>     treated as if it were converted by the intrinsic function INT(16.9.100)
>     to type integer with the kind type parameter of the variable.
do have a link for the current workinng documentation it'll be useful.
>
> For the second program, I get
>
> gfcx -o z a.f90 && ./z
> a.f90:8:26:
>
>      8 | logical(4) b / z'00000001' /
>        |                          1
> Error: BOZ at (1) cannot appear in an old-style initialization
>
> which to me is acceptable.

whoops, I added the wrong program, it should have had a DATA statement 
in it...

program test
    logical(4) b
    data b / z'00000001' /
    write(*, *) b
end program test

> For the first testcase, that should be rejected.  I thought I had
> that fixed in my tree.  It probably got lost in one of numerous
> versions of the BOZ rewrite.
>
>> Apologies if this should have been reported via bugzilla. If so let me
>> know and I'll submit it split into 2 or 3 bug reports.
> Reporting it here is fine.  I'll look at rejecting the one code
> that compiles (as it shouldn't).  And, I'll toy with adding BOZ
> as an operand of binary operators (I actually had this working in
> an ancient patch) under -fallow-invalid-boz.
>
>
regards,

Mark

-- 
https://www.codethink.co.uk/privacy.html



More information about the Gcc-patches mailing list