Created attachment 41805 [details] Example source code When the following three conditions are met (a) call to the intrinsic function IAND, IEOR, or IOR, and (b) one of its arguments is a boz-literal-constant, and (c) the -std=f2008 compilation flag is used, for example, write(*,*) ior(b'001011101',5) compilation aborts with the compilation error: Error: GNU Extension: Different type kinds at (1) with (1) also written below the left parenthesis after the intrinsic function. This should not be an error, since the 2008 version of the Fortran standard permits this: paragraph 3 "Arguments" of the subsections that define IAND(I,J), IEOR(I,J), and IOR(I,J) (13.7.72, 13.7.78, and 13.7.82, respectively) say: "I shall be of type integer or a boz-literal-constant. "J shall be of type integer or a boz-literal-constant. If both I and J are of type integer, they shall have the same kind type parameter. I and J shall not both be boz-literal-constants." Note that the cause for the error would not even make sense: boz-literal-constants don't have a type (as per paragraph 1, section 4.7 of the 2008 standard), and therefore they could not have a type kind that could match or not the type kind of the other argument of the intrinsic function. I am experiencing this with versions 6.4.0 and 7.1.0 - please see the attachments for an example that explores all combinations of boz constants and intrinsics, and the respective compiler outputs with detailed version information.
Created attachment 41806 [details] Compilation output - gfortran v6.4.0
Created attachment 41807 [details] Compilation output - gfortran v7.1.0
(1) Work around: wrap the boz-literal-constant inside an INT, e.g., program p implicit none write(*,*) iand(int(z'1A2B3C4D' ),3), iand(8, int(z'1A2B3C4D' )) write(*,*) ior(int(z'1A2B3C4D' ),3), ior(8, int(z'1A2B3C4D' )) write(*,*) ieor(int(z'1A2B3C4D' ),3), ieor(8, int(z'1A2B3C4D' )) write(*,*) iand(int(o'123456' ),4), iand(7, int(o'123456' )) write(*,*) ior(int(o'123456' ),4), ior(7, int(o'123456' )) write(*,*) ieor(int(o'123456' ),4), ieor(7, int(o'123456' )) write(*,*) iand(int(b'001011101'),5), iand(6, int(b'001011101')) write(*,*) ior(int(b'001011101'),5), ior(6, int(b'001011101')) write(*,*) ieor(int(b'001011101'),5), ieor(6, int(b'001011101')) end program p (2) From https://gcc.gnu.org/onlinedocs/gfortran/BOZ-literal-constants.html#BOZ-literal-constants > In all other cases, the BOZ literal constant is converted to an INTEGER value with the largest decimal representation. i.e., INTEGER(16) in 64-bit mode and INTEGER(8) in 32-bit mode. IMO it is compatible with > The processor shall allow the position of the leftmost nonzero bit to be > at least z - 1, where z is the maximum value that could result from invoking > the intrinsic function STORAGE_SIZE (13.8.175) with an argument that is > a real or integer scalar of any kind supported by the processor. Note that the (invalid, see pr54072) code program p implicit none print *, kind(iand(b'001011101',b'101')) print *, kind(ieor(b'001011101',b'101')) print *, kind(ior(b'001011101',b'101')) end program p gives 16 16 16 in 64-bit mode, and 8 8 8 in 32-bit mode. (3) I agree that the KIND should not be checked for boz-literal-constant.
A patch has been submitted. See https://gcc.gnu.org/ml/fortran/2017-09/msg00124.html
pr45513 and pr54072 could be duplicates.
On Wed, Sep 27, 2017 at 10:59:56PM +0000, dominiq at lps dot ens.fr wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81509 > > --- Comment #5 from Dominique d'Humieres <dominiq at lps dot ens.fr> --- > pr45513 and pr54072 could be duplicates. > I don't recall either of those PR's, and have no idea why I would have missed them. :-\ pr45513 should be covered by my patch. A portion of pr54072 is also covered, but pr54072 indicates a BOZ can be used with other intrinsic subprogramis, e.g., TRANSFER. This isn't surprizing as a boz is marked as a BT_INTEGER. That is, for gfc_expr x; a boz has x->ts.type = BT_INTEGER x->is_boz = 1 In hindsight, we probably should have introduced BT_BOZ and treat it has some opaque entity with helper functions. For example, gfc_boz2int(x,kind) would convert the BOZ in x to an INTEGER with kind type parameter 'kind'.
Author: kargl Date: Mon Dec 24 18:26:25 2018 New Revision: 267415 URL: https://gcc.gnu.org/viewcvs?rev=267415&root=gcc&view=rev Log: 2018-12-24 Steven G. Kargl <kargl@gcc.gnu.org> PR fortran/45513 PR fortran/81509 * check.c: Rename function gfc_check_iand to gfc_check_iand_ieor_ior. * check.c (boz_args_check): New function. Check I and J not both BOZ. (gfc_check_dshift,gfc_check_iand_ieor_ior, gfc_check_ishft, gfc_check_and, gfc_check_merge_bits): Use it. * check.c (gfc_check_iand_ieor_ior): Force conversion of BOZ to kind type of other agrument. Remove silly GNU extension. (gfc_check_ieor, gfc_check_ior): Delete now unused functions. * intrinsic.c (add_functions): Use gfc_check_iand_ieor_ior. Wrap long line. * intrinsic.h: Rename gfc_check_iand to gfc_check_iand_ieor_ior. Delete prototype for bool gfc_check_ieor and gfc_check_ior * intrinsic.texi: Update documentation for boz-literal-constant. 2018-12-24 Steven G. Kargl <kargl@gcc.gnu.org> PR fortran/45513 PR fortran/81509 * gfortran.dg/graphite/id-26.f03: Fix non-conforming use of IAND. * gfortran.dg/pr81509_1.f90: New test. * gfortran.dg/pr81509_2.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/pr81509_1.f90 trunk/gcc/testsuite/gfortran.dg/pr81509_2.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/check.c trunk/gcc/fortran/intrinsic.c trunk/gcc/fortran/intrinsic.h trunk/gcc/fortran/intrinsic.texi trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/graphite/id-26.f03
Fixed on trunk.