This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Committed] PR fortran/54072 -- More fun with BOZ
- From: Steve Kargl <sgk at troutmask dot apl dot washington dot edu>
- To: Mark Eggleston <mark dot eggleston at codethink dot co dot uk>
- Cc: fortran at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Wed, 7 Aug 2019 09:09:49 -0700
- Subject: Re: [Committed] PR fortran/54072 -- More fun with BOZ
- References: <20190723230520.GA33409@troutmask.apl.washington.edu> <9ca1a4cd-579d-d90d-4096-348740f70b71@codethink.co.uk>
- Reply-to: sgk at troutmask dot apl dot washington dot edu
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.
> 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.
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.
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.
--
Steve