Bug 54633 - ICEs and reject valid with MINLOC/MINVAL (MAXLOC/MAXVAL) due to lacking compile-time simplification
Summary: ICEs and reject valid with MINLOC/MINVAL (MAXLOC/MAXVAL) due to lacking compi...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code, rejects-valid
Depends on:
Blocks: 54613
  Show dependency treegraph
 
Reported: 2012-09-20 08:29 UTC by Tobias Burnus
Modified: 2017-09-24 14:01 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-07-27 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2012-09-20 08:29:33 UTC
Related to 54613, reported by James in the thread "Implicit" use of assignment(=)"
at https://groups.google.com/forum/?fromgroups=#!topic/comp.lang.fortran/5eAz5ns6AG0

Namely: https://groups.google.com/d/msg/comp.lang.fortran/5eAz5ns6AG0/G1uydcaGivkJ


ISSUES:

a) Wrong-code for minval4.f90?

With gfortran 4.3, it gets rejected with:
  
         integer x(minval((/1/)))
                                1
  Error: automatic object 'x' at (1) cannot have the SAVE attribute

interestingly, NAG f95 accepts it unless I use explicitly "save :: x", then it rejects it with:
  Error: minval4.f90, line 7: Static array X cannot have variable bounds

Thus, I am bit lost whether it is valid or not.


b) ICE with minloc/minval (minval2.f90, minloc2.f90):

   integer x(sum(minloc((/1/))))
respectively:
   integer x(minval((/1/),mask=(/.TRUE./)))

in gfc_trans_auto_array_allocation, at fortran/trans-array.c:5621

That's  gcc_assert (!TREE_STATIC (decl));  and decl is the var_decl "x".

The problem is that minloc/minval is not simplified to a constant. Other compilers do compile-time evaluate this.

(Or they don't? Cf. (a).)


c) minval3.f90: This program compiles in gfortran with -std=f95 but other compilers reject it with:
   MINVAL function is not permitted in an initialization expression

   integer, parameter :: m = minval((/1/))

I don't see ad hoc why the other compilers do accept in in (b) but not in (c).
Comment 1 Tobias Burnus 2012-09-20 09:00:45 UTC
See also related: pr25104 and pr45689 - and PR54613.

I forgot to quote the output of the different compilers:

minloc1.f90 REJECTED REJECTED REJECTED  REJECTED REJECTED
minloc2.f90      ICE        1      ICE 538976289        1
minval1.f90 REJECTED REJECTED REJECTED  REJECTED REJECTED
minval2.f90      ICE   ACCVIO      ICE         1        1
minval3.f90  17.0, 4 REJECTED REJECTED  REJECTED REJECTED
minval4.f90        2   ACCVIO      ICE         1        1


mincloc1, minval1 and minval3 are invalid Fortran 95 but valid Fortran 2003. gfortran's result for minval3 is correct - the rejects are due to due to a lacking simplify.

min*2.f90: Those are interesting, the program is valid Fortran 95 and valid Fortran 2003, but the result is different. In Fortran 95 the expected result is 1, in Fortran 2003 the expected result is 2. (See below.)
Again, gfortran lacks a simplification - or a guard to catch (and reject) the programs where the simplify is lacking.

  * * *

Looking at Fortran 95's "7.1.6.1 Constant expression", {min,max}{loc,val} aren't constant expressions; nor are they "initialization expressions".

Looking at Fortran 2003's "7.1.7 Initialization expression", they are:

"(5) A reference to a transformational standard intrinsic function other than
     NULL, where each argument is an initialization expression,"
as {min,max}{loc,val} are in the "Class. Transformational function."

  * * *

Regarding the SAVE:

F95 has in "5.2.4 SAVE statement":
"A SAVE statement without a saved entity list is treated as though it contained the names of all allowed items in the same scoping unit."

As with -std=f95, automatic variables don't have the SAVE attribute, as MINLOC is not an initialization expression, "x" is not SAVE. With -std=f2003, MINLOC is an initialization expression ...

Fortran 2003 contains the same:
"A SAVE statement without a saved entity list is treated as though it contained the names of all allowed items in the same scoping unit."


Thus, in Fortran 2003, SAVE doesn't apply to "X", in Fortran 95 it does.


As Bob Covert points out, that's a known problem:

"1.6.4 Fortran 90 compatibility"

"The following Fortran 90 features have dierent interpretations in this part of ISO/IEC 1539:" [...]
"* whether an expression is a constant expression (thus whether a variable is considered to be automatic)."


The question is whether we want to do something about or not.
Comment 2 Tobias Burnus 2012-09-20 09:21:43 UTC
(In reply to comment #1)
> As Bob Covert points out, that's a known problem:

Make that Bob Corbett (of Oracle), who quickly answered my question to the J3 list. (Thanks to him - and sorry for mistyping the name.)
Comment 3 Dominique d'Humieres 2013-07-27 16:54:17 UTC
The compilers are missing in comment #1:

    Program gfortran    ifort      g95     ftn95     lf95 
minloc1.f90 REJECTED REJECTED REJECTED  REJECTED REJECTED 
minloc2.f90      ICE        1      ICE 538976289        1 
minval1.f90 REJECTED REJECTED REJECTED  REJECTED REJECTED 
minval2.f90      ICE   ACCVIO      ICE         1        1 
minval3.f90  17.0, 4 REJECTED REJECTED  REJECTED REJECTED 
minval4.f90        2   ACCVIO      ICE         1        1
Comment 4 Thomas Koenig 2017-09-24 09:07:54 UTC
integer x(minval((/1/))) is accepted now.

integer y((sum(minloc((/1/)))) is rejected with the
(IMHO misleading) error message

   integer y((sum(minloc((/1/))))
                                1
Error: Expected another dimension in array declaration at (1)

integer x(minval((/1/),mask=(/.TRUE./)))

is accepted.

  integer, parameter :: m = minval((/1/))

is now rejected with -std=f95 and accepted by default:

   integer, parameter :: m = minval((/1/))
                           1
Error: Fortran 2003: Transformational function 'minval' at (1) is invalid in an initialization expression

So, this PR is mostly fixed except for the sum(minloc(((1))) issue.
Comment 5 Dominique d'Humieres 2017-09-24 12:57:14 UTC
> So, this PR is mostly fixed except for the sum(minloc(((1))) issue.

Why not opening a new PR for the remaining issue and closing this one as FIXED?
Comment 6 Thomas Koenig 2017-09-24 13:52:10 UTC
Author: tkoenig
Date: Sun Sep 24 13:51:39 2017
New Revision: 253125

URL: https://gcc.gnu.org/viewcvs?rev=253125&root=gcc&view=rev
Log:
2017-09-24  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/54633
	* gfortran.dg/intrinsic_bounds_1.f90: New test.
	* gfortran.dg/intrinsic_param_1.f90: New test.


Added:
    trunk/gcc/testsuite/gfortran.dg/intrinsic_bounds_1.f90
    trunk/gcc/testsuite/gfortran.dg/intrinsic_param_1.f90
Modified:
    trunk/gcc/testsuite/ChangeLog
Comment 7 Thomas Koenig 2017-09-24 14:01:35 UTC
The remaining bug is now PR 82313.