Created attachment 38415 [details] A simplified program generating the inappropriate error The file module test_int use, intrinsic:: iso_fortran_env integer(int64), parameter :: & e18 = 1000000000000000000_int64, & e19 = ( -huge(1_int64) + & (e18-223372036854775807_int64) & ) - 2 end module test_int when compiled using fortran -std=f2008 -fmax-errors=10 -Wall -Wimplicit-interface -O3 -fbacktrace -fwhole-file -I mod_dir -c -o test_int.o test_int.f90 on Mac OS X version 10.11.4 with version gfortran --version GNU Fortran (GCC) 6.1.0 Copyright (C) 2016 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. produces the message test_int.f90:5:11: e18 = 1000000000000000000_int64, & 1 Warning: Change of value in conversion from ‘INTEGER(8)’ to ‘REAL(4)’ at (1) [-Wconversion] This suggests that the front end is assigning the wrong type to at least one of e18 e19 or the expression ( -huge(1_int64) + (e18-223372036854775807_int64) ) - 2 According to Dominique D'Humières the following simplified code has the result ! integer(8), parameter :: e18 = 10000000000_8 integer(8), parameter :: e18 = 100000000000_8 integer(8), parameter :: e19 = (e18) ! integer(8), parameter :: e19 = e18 print *, e18, e19 end warn_conv_db_3.f90:2:32: integer(8), parameter :: e18 = 100000000000_8 1 Warning: Change of value in conversion from 'INTEGER(8)' to 'REAL(4)' at (1) [-Wconversion] The warning is gone if I remove the parentheses in e19 = (e18) or if I replace 100000000000_8 with 10000000000_8. which suggests that e18 is being assigned the inappropriate type due to the appearance of (e18) in the definition of e19
With the parenthesis around the constant, it is being interpreted as a complex number. The check in arith.c is taking this as a component of the complex constant. match_complex_constant in primary.c probably returns a MATCH_NO, but I think the warning is occurring in the middle of the attempted matching process. #0 gfc_warning_now (opt=opt@entry=201, gmsgid=gmsgid@entry=0x140c530 "Change of value in conversion from %qs to %qs at %L") at ../../trunk/gcc/fortran/error.c:1148 #1 0x000000000062e0ce in gfc_int2real (src=0x1ff3db0, kind=4) at ../../trunk/gcc/fortran/arith.c:2079 #2 0x00000000006abb35 in match_sym_complex_part (result=0x7fffffffd400) at ../../trunk/gcc/fortran/primary.c:1289 #3 match_complex_part (result=0x7fffffffd400) at ../../trunk/gcc/fortran/primary.c:1314 #4 0x00000000006abbc2 in match_complex_constant ( result=result@entry=0x7fffffffd690) at ../../trunk/gcc/fortran/primary.c:1347
This is a regression due to r224190.
I have tried changing the matching order so that integer constants are matched before real or complex. It fixes the reported problem but results in numerous test suite failures. I wonder. If we just change the warning message to "possible change of value in conversion ... " would this be sufficient? It is only a warning. Otherwise we will have to work on some fairly intricate code. The revision mentioned in comment #2 only added the warning feature, it did not change the matching codes.
As shown by the following reduced test integer(8), parameter :: e18 = 100000000000_8 integer(8) :: e19 e19= (e18) print *, e18, e19 end there are two issues: (1) a bogus warning, (2) more annoying, the warning is misplaced, hence misleading. IMO if one tries to fix this PR the priority should be the second issue.
1. Maybe the placement of the warning is spurious, but is there any chance it is actually assigning the type REAL(4) to e18? 2. It sounds as if the logic of arith.c is in an incorrect order. What should be done is roughly? Is this a parenthesized expression? If yes is the expression comma deliminated? If yes is it a single comma delimination? If yes is the first part REAL(4)? If yes is the second part REAL(4)? If yes then it is a COMPLEX(8) expression Else the parts are inconsistent in type and might be recognized as an extension Else if no is the first part REAL(8)? If yes then is the second part REAL(8) expression If yes then it is a COMPLEX(16) expression Else the parts are inconsistent in type and might be recognized as an extension Else is the first part another type you want to allow as an extension ... Else is it a multi comma deliminated expression? if yes then a syntax error, unrecognized expression Else it is a scalar expression of the type of the "first" expression 3. By the above if it mistakenly recognizing a complex constant I would expect it to be to a OMPLEX(16) constant. The message reads as if it might be converting the INTEGER(8) to REAL(8) then deciding that it is part of a COMPLEX(8) constant.
> 1. Maybe the placement of the warning is spurious, but is there any chance it > is actually assigning the type REAL(4) to e18? I don't think so as shown by the results 37037036703703701 37037036703703701 37037036296732672 37037036703703704 of the following test: integer(8), parameter :: e1 = 3 * 12345678901234567_8 integer(8) :: e2, e3, e4 real(4) :: a real(8) :: b e2 = (e1) a = e1 b = e1 e3 = a e4 = b print *, e1, e2, e3, e4 end
GCC 6.2 is being released, adjusting target milestone.
Fixed with https://gcc.gnu.org/viewcvs?rev=241689&root=gcc&view=rev , also fixed on gcc 6. Closing.