Bug 58498 - Bogus "Invalid kind for INTEGER"
Summary: Bogus "Invalid kind for INTEGER"
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2013-09-22 08:38 UTC by janus
Modified: 2021-12-18 02:43 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-12-17 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description janus 2013-09-22 08:38:49 UTC
Reported by James van Buskirk at https://groups.google.com/forum/?fromgroups#!topic/comp.lang.fortran/hb2_DNa5ylY

Considering the (supposedly valid) code:


module intkinds
   implicit none
   private
   integer, parameter :: Kmax = 10
   integer, parameter :: K1 = selected_int_kind(1)
   integer, parameter :: tK2 = selected_int_kind(range(0_K1)+1)
   integer, parameter :: cK2 = (sign(1,tK2)+1)/2
   integer, parameter :: K2 = cK2*tK2+(1-cK2)*K1
   integer, parameter :: tK3 = selected_int_kind(range(0_K2)+1)
   integer, parameter :: cK3 = (sign(1,tK3)+1)/2
   integer, parameter :: K3 = cK3*tK3+(1-cK3)*K2
   integer, parameter :: tK4 = selected_int_kind(range(0_K3)+1)
   integer, parameter :: cK4 = (sign(1,tK4)+1)/2
   integer, parameter :: K4 = cK4*tK4+(1-cK4)*K3
   integer, parameter :: tK5 = selected_int_kind(range(0_K4)+1)
   integer, parameter :: cK5 = (sign(1,tK5)+1)/2
   integer, parameter :: K5 = cK5*tK5+(1-cK5)*K4
   integer, parameter :: tK6 = selected_int_kind(range(0_K5)+1)
   integer, parameter :: cK6 = (sign(1,tK6)+1)/2
   integer, parameter :: K6 = cK6*tK6+(1-cK6)*K5
   integer, parameter :: tK7 = selected_int_kind(range(0_K6)+1)
   integer, parameter :: cK7 = (sign(1,tK7)+1)/2
   integer, parameter :: K7 = cK7*tK7+(1-cK7)*K6
   integer, parameter :: tK8 = selected_int_kind(range(0_K7)+1)
   integer, parameter :: cK8 = (sign(1,tK8)+1)/2
   integer, parameter :: K8 = cK8*tK8+(1-cK8)*K7
   integer, parameter :: tK9 = selected_int_kind(range(0_K8)+1)
   integer, parameter :: cK9 = (sign(1,tK9)+1)/2
   integer, parameter :: K9 = cK9*tK9+(1-cK9)*K8
   integer, parameter :: tK10 = selected_int_kind(range(0_K9)+1)
   integer, parameter :: cK10 = (sign(1,tK10)+1)/2
   integer, parameter :: K10 = cK10*tK10+(1-cK10)*K9
   integer, parameter :: iKsize = 1+cK2+cK3+cK4+cK5+cK6+cK7+cK8+cK9+cK10
   integer, parameter :: tKINDS(Kmax) = (/K1,K2,K3,K4,K5,K6,K7,K8,K9,K10/)
   integer, parameter, public :: iKINDS(iKsize) = tKINDS(1:iKsize)
end module intkinds

program testme
   use intkinds
   implicit none
   integer iRANGES(size(iKINDS))
   integer i

   iRANGES = (/(range(int(0,iKINDS(i))),i=1,size(iKINDS))/)
   write(*,*) 'iKINDS = ',iKINDS
   write(*,*) 'iRANGES = ', iRANGES
end program testme  


This is rejected by gfortran 4.7 and earlier with:

   iRANGES = (/(range(int(0,iKINDS(i))),i=1,size(iKINDS))/)
                            1
Error: 'kind' argument of 'int' intrinsic at (1) must be a constant


4.8 and trunk report:

   iRANGES = (/(range(int(0,iKINDS(i))),i=1,size(iKINDS))/)
                            1
Error: Invalid kind for INTEGER at (1)


Both errors are apparently wrong, since the KIND argument to the intrinsic INT shall be a scalar integer initialization expression, which it seems to be in this case (for further details and standard quotes see the c.l.f. thread).
Comment 1 janus 2013-09-22 08:50:56 UTC
As reported by Richard Maine in the c.l.f. thread, NAG compiles the code and produces the following output:

 iKINDS =  1 2 3 4
 iRANGES =  2 4 9 18 


When commenting out the lines with 'iRANGES', gfortran prints:

 iKINDS =            1           2           4           8          16
Comment 2 janus 2013-09-22 09:29:29 UTC
With this patch ...

Index: gcc/fortran/check.c
===================================================================
--- gcc/fortran/check.c (revision 202812)
+++ gcc/fortran/check.c (working copy)
@@ -173,8 +173,8 @@ kind_check (gfc_expr *k, int n, bt type)
   if (gfc_extract_int (k, &kind) != NULL
       || gfc_validate_kind (type, kind, true) < 0)
     {
-      gfc_error ("Invalid kind for %s at %L", gfc_basic_typename (type),
-                &k->where);
+      gfc_error ("Invalid kind '%i' for %s at %L", kind,
+                gfc_basic_typename (type), &k->where);
       return false;
     }


... the output is:

   iRANGES = (/(range(int(0,iKINDS(i))),i=1,size(iKINDS))/)
                            1
Error: Invalid kind '0' for INTEGER at (1)


This is strange, since none of the iKINDS is zero (as comment 1 shows). In any case, this extension of the error message might be helpful in situations like this, where the kind is not directly supplied by a number, but by some initialization expression ...
Comment 3 Dominique d'Humieres 2013-09-22 10:28:22 UTC
I get the same error if I replace

   iRANGES = (/(range(int(0,iKINDS(i))),i=1,size(iKINDS))/)

with

   do i = 1, size(iKINDS)
     print *, range(int(0,iKINDS(i)))
   end do

while

   print *, range(int(0,iKINDS(1)))
   print *, range(int(0,iKINDS(2)))
   ...

gives the right answer. I think "print *, range(int(0,iKINDS(i)))" is invalid, however I cannot convince myself that
   iRANGES = (/(range(int(0,iKINDS(i))),i=1,size(iKINDS))/)
is. If I am right, it seems that iKINDS(i) is not "expanded" as a constant in the constructor.

The following code is working as expected

module intkinds
   implicit none
   private
   integer, parameter :: Kmax = 10
   integer, parameter :: K1 = selected_int_kind(1)
   integer, parameter :: rK1 = range(int(0,K1))
   integer, parameter :: tK2 = selected_int_kind(range(0_K1)+1)
   integer, parameter :: cK2 = (sign(1,tK2)+1)/2
   integer, parameter :: K2 = cK2*tK2+(1-cK2)*K1
   integer, parameter :: rK2 = range(int(0,K2))
   integer, parameter :: tK3 = selected_int_kind(range(0_K2)+1)
   integer, parameter :: cK3 = (sign(1,tK3)+1)/2
   integer, parameter :: K3 = cK3*tK3+(1-cK3)*K2
   integer, parameter :: rK3 = range(int(0,K3))
   integer, parameter :: tK4 = selected_int_kind(range(0_K3)+1)
   integer, parameter :: cK4 = (sign(1,tK4)+1)/2
   integer, parameter :: K4 = cK4*tK4+(1-cK4)*K3
   integer, parameter :: rK4 = range(int(0,K4))
   integer, parameter :: tK5 = selected_int_kind(range(0_K4)+1)
   integer, parameter :: cK5 = (sign(1,tK5)+1)/2
   integer, parameter :: K5 = cK5*tK5+(1-cK5)*K4
   integer, parameter :: rK5 = range(int(0,K5))
   integer, parameter :: tK6 = selected_int_kind(range(0_K5)+1)
   integer, parameter :: cK6 = (sign(1,tK6)+1)/2
   integer, parameter :: K6 = cK6*tK6+(1-cK6)*K5
   integer, parameter :: rK6 = range(int(0,K6))
   integer, parameter :: tK7 = selected_int_kind(range(0_K6)+1)
   integer, parameter :: cK7 = (sign(1,tK7)+1)/2
   integer, parameter :: K7 = cK7*tK7+(1-cK7)*K6
   integer, parameter :: rK7 = range(int(0,K7))
   integer, parameter :: tK8 = selected_int_kind(range(0_K7)+1)
   integer, parameter :: cK8 = (sign(1,tK8)+1)/2
   integer, parameter :: K8 = cK8*tK8+(1-cK8)*K7
   integer, parameter :: rK8 = range(int(0,K8))
   integer, parameter :: tK9 = selected_int_kind(range(0_K8)+1)
   integer, parameter :: cK9 = (sign(1,tK9)+1)/2
   integer, parameter :: K9 = cK9*tK9+(1-cK9)*K8
   integer, parameter :: rK9 = range(int(0,K9))
   integer, parameter :: tK10 = selected_int_kind(range(0_K9)+1)
   integer, parameter :: cK10 = (sign(1,tK10)+1)/2
   integer, parameter :: K10 = cK10*tK10+(1-cK10)*K9
   integer, parameter :: rK10 = range(int(0,K10))
   integer, parameter :: iKsize = 1+cK2+cK3+cK4+cK5+cK6+cK7+cK8+cK9+cK10
   integer, parameter :: tKINDS(Kmax) = (/K1,K2,K3,K4,K5,K6,K7,K8,K9,K10/)
   integer, parameter :: tRANGES(Kmax) = (/rK1,rK2,rK3,rK4,rK5,rK6,rK7,rK8,rK9,rK10/)
   integer, parameter, public :: iKINDS(iKsize) = tKINDS(1:iKsize)
   integer, parameter, public :: iRANGES(iKsize) = tRANGES(1:iKsize)
end module intkinds

program testme
   use intkinds
   implicit none
   integer i

   write(*,*) 'iKINDS = ',iKINDS
   write(*,*) 'iRANGES = ', iRANGES
end program testme
Comment 4 Francois-Xavier Coudert 2014-06-07 08:46:30 UTC
Reduced testcase, to summarize:

  integer, parameter :: arr(1) = [ 1 ]
  integer, parameter :: x(1) = [( range(int(0,arr(i))), i=1,1 )]
  integer :: i
  print *, x
  print *, range(int(0,arr(1)))
  end

Intel wrongly refuses to compile it ("A kind type parameter must be a compile-time constant"), and IBM compiles it but gives a wrong answer (range of -51378971).

So it's indeed tricky code. Both prints should output the same number.