Bug 70959 - [6/7 Regression] Invalid type determination due to expression in a type declaration statement
Summary: [6/7 Regression] Invalid type determination due to expression in a type decla...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 6.1.0
: P4 normal
Target Milestone: 6.3
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-05-05 02:09 UTC by William Clodius
Modified: 2016-11-01 09:47 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 5.3.0
Known to fail: 6.1.0, 7.0
Last reconfirmed: 2016-05-05 00:00:00


Attachments
A simplified program generating the inappropriate error (146 bytes, text/plain)
2016-05-05 02:09 UTC, William Clodius
Details

Note You need to log in before you can comment on or make changes to this bug.
Description William Clodius 2016-05-05 02:09:55 UTC
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
Comment 1 Jerry DeLisle 2016-05-05 05:38:23 UTC
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
Comment 2 Dominique d'Humieres 2016-05-05 09:06:54 UTC
This is a regression due to r224190.
Comment 3 Jerry DeLisle 2016-05-15 15:37:59 UTC
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.
Comment 4 Dominique d'Humieres 2016-05-16 12:45:50 UTC
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.
Comment 5 William Clodius 2016-05-17 04:23:33 UTC
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.
Comment 6 Dominique d'Humieres 2016-05-17 06:42:39 UTC
> 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
Comment 7 Richard Biener 2016-08-22 08:57:39 UTC
GCC 6.2 is being released, adjusting target milestone.
Comment 8 Richard Biener 2016-08-22 08:57:49 UTC
GCC 6.2 is being released, adjusting target milestone.
Comment 9 Richard Biener 2016-08-22 09:07:14 UTC
GCC 6.2 is being released, adjusting target milestone.
Comment 10 Richard Biener 2016-08-22 09:08:37 UTC
GCC 6.2 is being released, adjusting target milestone.
Comment 11 Thomas Koenig 2016-11-01 09:47:16 UTC
Fixed with https://gcc.gnu.org/viewcvs?rev=241689&root=gcc&view=rev , also fixed on gcc 6. Closing.