[Patch, Fortran] PR 92996 – fix rank resolution EXPR_ARRAY

Tobias Burnus tobias@codesourcery.com
Thu Dec 19 20:31:00 GMT 2019


Hi all,

expressions initially have "expr->rank = 0" (cf. gfc_match_rvalue, 
called by match_expr). This is later fixed during the resolution in 
"expression_rank", which is called by (gfc_)resolve_ref, which in turn 
is called by gfc_resolve_expr. Additionally, the resolve_array_ref 
ensures that the number of specified indices matches the rank.

However, if one calls gfc_simplify_expr, array-valued FL_PARAMETER are 
converted to EXPR_ARRAY. As they are a somewhat amorphous object, a 
later call of "expression_rank" is a no-op and the interesting 
information is already gone.

Hence, we need to resolve the FL_PARAMETER EXPR_VARIABLE before 
converting it to EXPR_ARRAY. We cannot call gfc_resolve_expr as 
resolve_variable in turn calls gfc_simplify_expr – repeating this until 
one runs out of stack space.

Hence: We now call gfc_resolve_ref explicitly before conversion to 
EXPR_ARRAY – and gfc_expression_rank. And the accumulated errors are 
forced to be output; in principle, this could be done by the caller – 
but my feeling is that it is easily forgotten and ignoring this error 
does not make much sense; hence, I force it.

Additionally, when creating EXPR_ARRAY, the location is now set to the 
usage of the parameter-variable. Before, it pointed to the place where 
the variable was initialized, i.e. "sym->value->where" (due to  
gfc_copy_expr (...->value).

As minor cleanup, I remove "gfc_init_expr_flag" before the call to 
gfc_reduce_init_expr as the callee already sets those variables and also 
cleaned up expression_rank a tiny bit.

* * *

Side-effect of the changed location: without the patch, one gets
     5 |    integer, parameter :: a(2) = [2,0]              ! { dg-error "Element with a value of" }
       |                               1
     6 |    print *, reshape([1,2,3,4,5,6], [2,3], order=a) ! { dg-error "for the RESHAPE intrinsic near" }
       |                                   2
Error: Element with a value of 0 in ORDER at (1) must be in the range [1, ..., 2] for the RESHAPE intrinsic near (2)

which is a bit nicer than the new

     6 |    print *, reshape([1,2,3,4,5,6], [2,3], order=a) ! { dg-error "for the RESHAPE intrinsic near" }
       |                                   2            1
Error: Element with a value of 0 in ORDER at (1) must be in the range [1, ..., 2] for the RESHAPE intrinsic near (2)


On the other hand, without that change, one gets:
    10 |    stop a ! { dg-error "STOP code at .1. must be scalar" }
       |       1
Error: STOP code at (1) must be scalar
instead of
     8 |   integer, parameter :: a(2) = [1, 2]
       |                         1
Error: STOP code at (1) must be scalar

The latter could be "solved" by using %C instead of %L after
gfc_simplify_expr in gfc_match_stopcode.
[The "ref" has its own address (e->ref->u.ar->where); hence,
the a(1,1) error would be still fine.]
(Though, this potentially effects more.)

Thoughts?

  * * *

Build and regtested on x86-64-gnu-linux.
OK for the trunk?

Cheers,

Tobias

-------------- next part --------------
A non-text attachment was scrubbed...
Name: expr_array.diff
Type: text/x-patch
Size: 9496 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20191219/2d8b717b/attachment.bin>


More information about the Fortran mailing list