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