Bug 48831

Summary: check.c: Constant expression (PARAMETER array element) rejected as nonconstant
Product: gcc Reporter: Tobias Burnus <burnus>
Component: fortranAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: major CC: burnus
Priority: P3 Keywords: rejects-valid
Version: 4.7.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:
Bug Depends on:    
Bug Blocks: 32834    

Description Tobias Burnus 2011-04-30 09:45:26 UTC
I know that this PR is a duplicate of some PR which I cannot find.

http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/d0bd8bd1803b626e has the following program, which is rejected with:


    i3 = int(0, i2(1))  ! This line gives an error when compiling.
                1
Error: 'kind' argument of 'int' intrinsic at (1) must be a constant


In check.c, there is a simple expr_type == EXPR_CONSTANT check; however, using gfc_is_constant_expr() doesn't work either as PARAMETER (arrays) are not recognized as being constant. (EXPR_VARIABLE + FL_PARAMETER.)

I think expr.c's check_init_expr might be better (it is currently static); however, I have the feeling all checks are wrong.

Note: Fortran 95 distinguishes between initialization and constant expressions, in Fortran 2003 and Fortran 2008 they have been merged to a single type - called "initialization expressions" in Fortran 2003 and "constant expressions" in Fortran 2008.

TODO:
- Find out what F90's constant and init expressions mean
- Make the less powerful call the more powerful, except for -std=f95
- Add checks for init/constant following the F95 pattern everywhere instead of using the half-baked EXPR_CONST or some made up test which check more, but only locally (e.g. const_expr + const array, as done in simplify.c)


Note: The case below should unaffected by the const/init change and should be already valid Fortran 95.

program p1
    implicit none
    integer, parameter  :: i1    = kind(0)
    integer, parameter  :: i2(1) = [i1]
    integer(kind=i2(1)) :: i3

    i3 = int(0, i1)
    print *, i3

    i3 = int(0, i2(1))  ! This line gives an error when compiling.
    print *, i3
end program p1
Comment 1 Tobias Burnus 2012-06-03 13:21:55 UTC
Author: burnus
Date: Sun Jun  3 13:21:50 2012
New Revision: 188152

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=188152
Log:
2012-06-03  Alessandro Fanfarillo  <fanfarillo.gcc@gmail.com>
            Tobias Burnus  <burnus@net-b.de>

        PR fortran/48831
        * gfortran.h (gfc_check_init_expr): Add prototype declaration
        of function.
        * check.c (kind_check): Change if condition to use
        to gfc_check_init_expr.
        * expr.c (check_init_expr): Remove forward declaration
        and static keyword. Change name in gfc_check_init_expr.

2012-06-03  Alessandro Fanfarillo  <fanfarillo.gcc@gmail.com>

        PR fortran/48831
        * gfortran.dg/parameter_array_element_2.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/parameter_array_element_2.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/check.c
    trunk/gcc/fortran/expr.c
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/testsuite/ChangeLog
Comment 2 Tobias Burnus 2012-06-03 13:29:36 UTC
FIXED on the trunk (4.8).

Thanks Alessandro for the patch!