Message ID | 20190723230520.GA33409@troutmask.apl.washington.edu |
---|---|
State | New |
Headers | show |
Series | [Committed] PR fortran/54072 -- More fun with BOZ | expand |
Steve, 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: character variables (9.1) * old style initialisation - not allowed (Incompatible types) * new style initialisation - not allowed (Cannot convert) * assignment - not allowed (Cannot convert) * DATA statement not allowed character variables (trunk with -fallow-invalid-boz) * old style initialisation - not allowed (type mismatch) * new style initialisation - not allowed (Unclassifiable statement) * assignment - not allowed (Invalid use) * DATA statement allowed logical variables (9.1) * old style initialisation - not allowed (Incompatible types) * new style initialisation - allowed with warning * assignment - allowed with warning * DATA statement not allowed (Incompatible types) logical variables (trunk with -fallow-invalid-boz) * old style initialisation - not allowed (type mismatch) * new style initialisation - not allowed (Unclassifiable statement) * assignment - not allowed (invalid use) * DATA statement allowed 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] 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. 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 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. The trunk compiler was built on x86_64 hardware using code from Subversion revision 274157. regards, Mark Eggleston On 24/07/2019 00:05, Steve Kargl wrote: > I've committed the attached patch as a follow-up to > the recent BOZ (r273747). It removes a few leftover > comments as well as fixes the PR. > > 2019-07-23 Steven G. Kargl <kargl@gcc.gnu.org> > > PR fortran/54072 > * check.c (gfc_invalid_boz): Fix comment. > (illegal_boz_arg): New function. > (gfc_check_transfer): Use to arguments. > (gfc_check_storage_size): Ditto. > (gfc_check_complex): Remove leftover comment from BOZ patch. > * primary.c (match_boz_constant): Remove leftover comment. > > > 2019-07-23 Steven G. Kargl <kargl@gcc.gnu.org> > > PR fortran/54072 > * gfortran.dg/illegal_boz_arg_1.f90: New tests. >
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.
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) BTW, -fallow-invalid-boz does enable all previous broken usages of BOZ. For example, BOZ can be an actual argument in only a few intrinsic subprograms listed in F2018. I've allowed only a few exceptions such as AND(z'1234',4242) which mirros IAND() is documented behavior. PS: Have you gotten write access to the source code repository, yet?
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. > > BTW, -fallow-invalid-boz does enable all previous broken > usages of BOZ. 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 regards, Mark > For example, BOZ can be an actual argument > in only a few intrinsic subprograms listed in F2018. I've > allowed only a few exceptions such as AND(z'1234',4242) > which mirros IAND() is documented behavior. > > PS: Have you gotten write access to the source code repository, yet? >
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
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.
On Thu, Aug 08, 2019 at 10:11:39AM +0100, Mark Eggleston wrote: > > >> 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. Because, I choose not to support invalid code. One would need to add a bunch of code to expr.c(simplify_intrinsic_op) to detect the BOZ usage and report an error or warning and then do some conversion. What does one do with if (z'12' .eq. z'4312') Is this a hard error because both operands are BOZ? Do you truncate the rhs operand or pad the lhs operand? Do you simply convert these to INTEGER(16) and let the compiler generate 128-bit integer code? For the case if (i .eq. z'1234') ! assuming i is integer A conversion of the BOZ to the type and kind type of 'i' is possible. Do we restrict the conversion to only rational operators? Do we restrict the conversion to only integer comparisons? What should this code do? x = 4 * atan(1.) + 1 if (x .ge. z'40490FDB') print* , x end with gfortran 9, when compiled and executed it does not produce output. Should z'40490FDB' be converted to the type and kind of x? In that case, gfortran-trunk would print out 4.14159..., which is incompatiable with previous gfortran 9 and older. What should be done with unary operators? i = - z'1234' ! Assume i is integer. The evaluation of the rhs is done first, and then assigned to 'i' where possible conversion is done. > 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. Yes, fixing the code would be preferred. > >> 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 Thanks, I take a look at this. It should be rejected.
On Thu, Aug 08, 2019 at 09:23:11AM -0700, Steve Kargl wrote: > On Thu, Aug 08, 2019 at 10:11:39AM +0100, Mark Eggleston wrote: > > > > >> 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. > > Because, I choose not to support invalid code. One would need > to add a bunch of code to expr.c(simplify_intrinsic_op) to > detect the BOZ usage and report an error or warning and then > do some conversion. What does one do with Ugh. expr.c(simplify_intrinsic_op) would need updates if we do some sort of constant-folding of BOZs. For resolution of 'if (i .eq. z"123")' one gets to resolve.c(resolve_operator). The same questions still apply.
Index: gcc/fortran/check.c =================================================================== --- gcc/fortran/check.c (revision 273747) +++ gcc/fortran/check.c (working copy) @@ -35,10 +35,10 @@ along with GCC; see the file COPYING3. If not see #include "target-memory.h" /* A BOZ literal constant can appear in a limited number of contexts. - gfc_invalid_boz() is a help function to simplify error/warning generation. - Note, gfortran accepts the nonstandard 'X' for 'Z' the nonstandard - suffix location. If -fallow-invalid-boz is used, then issue a warning; - otherwise issue an error. */ + gfc_invalid_boz() is a helper function to simplify error/warning + generation. gfortran accepts the nonstandard 'X' for 'Z', and gfortran + allows the BOZ indicator to appear as a suffix. If -fallow-invalid-boz + is used, then issue a warning; otherwise issue an error. */ bool gfc_invalid_boz (const char *msg, locus *loc) @@ -54,6 +54,20 @@ gfc_invalid_boz (const char *msg, locus *loc) } +/* Issue an error for an illegal BOZ argument. */ +static bool +illegal_boz_arg (gfc_expr *x) +{ + if (x->ts.type == BT_BOZ) + { + gfc_error ("BOZ literal constant at %L cannot be an actual argument " + "to %qs", &x->where, gfc_current_intrinsic); + return true; + } + + return false; +} + /* Some precedures take two arguments such that both cannot be BOZ. */ static bool @@ -2202,8 +2216,6 @@ gfc_check_co_sum (gfc_expr *a, gfc_expr *result_image, bool gfc_check_complex (gfc_expr *x, gfc_expr *y) { - - /* FIXME BOZ. What to do with complex? */ if (!boz_args_check (x, y)) return false; @@ -5894,6 +5906,12 @@ gfc_check_transfer (gfc_expr *source, gfc_expr *mold, return false; } + if (source->ts.type == BT_BOZ && illegal_boz_arg (source)) + return false; + + if (mold->ts.type == BT_BOZ && illegal_boz_arg (mold)) + return false; + /* MOLD shall be a scalar or array of any type. */ if (mold->ts.type == BT_PROCEDURE && mold->symtree->n.sym->attr.subroutine == 1) @@ -7124,6 +7142,9 @@ gfc_check_storage_size (gfc_expr *a, gfc_expr *kind) gfc_current_intrinsic, &a->where); return false; } + + if (a->ts.type == BT_BOZ && illegal_boz_arg (a)) + return false; if (kind == NULL) return true; Index: gcc/fortran/primary.c =================================================================== --- gcc/fortran/primary.c (revision 273747) +++ gcc/fortran/primary.c (working copy) @@ -494,7 +494,6 @@ match_boz_constant (gfc_expr **result) e->boz.str = XCNEWVEC (char, length + 1); strncpy (e->boz.str, buffer, length); - /* FIXME BOZ. */ if (!gfc_in_match_data () && (!gfc_notify_std(GFC_STD_F2003, "BOZ used outside a DATA " "statement at %L", &e->where))) Index: gcc/testsuite/gfortran.dg/illegal_boz_arg_1.f90 =================================================================== --- gcc/testsuite/gfortran.dg/illegal_boz_arg_1.f90 (nonexistent) +++ gcc/testsuite/gfortran.dg/illegal_boz_arg_1.f90 (working copy) @@ -0,0 +1,9 @@ +! { dg-do compile } +program foo + implicit none + integer :: i = 42 + print *, storage_size(z'1234') ! { dg-error "cannot be an actual" } + print *, transfer(z'1234', i) ! { dg-error "cannot be an actual" } + print *, transfer(i, z'1234') ! { dg-error "cannot be an actual" } + print *, transfer(i, i, z'1234') ! { dg-error "must be INTEGER" } +end program foo