Bug 81509 - Wrong compilation error: iand/ieor/ior + boz + -std=f2008
Summary: Wrong compilation error: iand/ieor/ior + boz + -std=f2008
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: unknown
: P4 normal
Target Milestone: 9.0
Assignee: kargls
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-07-21 16:28 UTC by ripero84
Modified: 2018-12-24 18:29 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-07-26 00:00:00


Attachments
Example source code (171 bytes, text/plain)
2017-07-21 16:28 UTC, ripero84
Details
Compilation output - gfortran v6.4.0 (1.22 KB, text/plain)
2017-07-21 16:36 UTC, ripero84
Details
Compilation output - gfortran v7.1.0 (1.18 KB, text/plain)
2017-07-21 16:37 UTC, ripero84
Details

Note You need to log in before you can comment on or make changes to this bug.
Description ripero84 2017-07-21 16:28:25 UTC
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.
Comment 1 ripero84 2017-07-21 16:36:09 UTC
Created attachment 41806 [details]
Compilation output - gfortran v6.4.0
Comment 2 ripero84 2017-07-21 16:37:15 UTC
Created attachment 41807 [details]
Compilation output - gfortran v7.1.0
Comment 3 Dominique d'Humieres 2017-07-26 13:28:19 UTC
(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.
Comment 4 kargls 2017-09-27 19:38:31 UTC
A patch has been submitted.  See

https://gcc.gnu.org/ml/fortran/2017-09/msg00124.html
Comment 5 Dominique d'Humieres 2017-09-27 22:59:56 UTC
pr45513 and pr54072 could be duplicates.
Comment 6 Steve Kargl 2017-09-27 23:20:32 UTC
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'.
Comment 7 kargls 2018-12-24 18:26:56 UTC
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
Comment 8 kargls 2018-12-24 18:29:05 UTC
Fixed on trunk.