When adding the initializer for an array, we need to make sure that array bounds are properly simplified if that array is a PARAMETER. Otherwise the generated initializer could be wrong and screw up subsequent simplifications, see PR.
The minimal solution is to attempt simplification of array bounds before adding the initializer as in the attached patch. (We could place that part in a helper function if this functionality is considered useful elsewhere). Regtested on x86_64-pc-linux-gnu. OK for mainline? Thanks, Harald Fortran - ensure simplification of bounds of array-valued named constants gcc/fortran/ChangeLog: PR fortran/82314 * decl.c (add_init_expr_to_sym): For proper initialization of array-valued named constants the array bounds need to be simplified before adding the initializer. gcc/testsuite/ChangeLog: PR fortran/82314 * gfortran.dg/pr82314.f90: New test.
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 2e49a673e15..f2e8896b562 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -2169,6 +2169,24 @@ add_init_expr_to_sym (const char *name, gfc_expr **initp, locus *var_locus) sym->as->type = AS_EXPLICIT; } + /* Ensure that explicit bounds are simplified. */ + if (sym->attr.flavor == FL_PARAMETER && sym->attr.dimension + && sym->as->type == AS_EXPLICIT) + { + for (int dim = 0; dim < sym->as->rank; ++dim) + { + gfc_expr *e; + + e = sym->as->lower[dim]; + if (e->expr_type != EXPR_CONSTANT) + gfc_reduce_init_expr (e); + + e = sym->as->upper[dim]; + if (e->expr_type != EXPR_CONSTANT) + gfc_reduce_init_expr (e); + } + } + /* Need to check if the expression we initialized this to was one of the iso_c_binding named constants. If so, and we're a parameter (constant), let it be iso_c. diff --git a/gcc/testsuite/gfortran.dg/pr82314.f90 b/gcc/testsuite/gfortran.dg/pr82314.f90 new file mode 100644 index 00000000000..3a147e22711 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr82314.f90 @@ -0,0 +1,11 @@ +! { dg-do run } +! PR fortran/82314 - ICE in gfc_conv_expr_descriptor + +program p + implicit none + integer, parameter :: karray(merge(3,7,.true.):merge(3,7,.false.)) = 1 + integer, parameter :: i = size (karray) + integer, parameter :: l = lbound (karray,1) + integer, parameter :: u = ubound (karray,1) + if (l /= 3 .or. u /= 7 .or. i /= 5) stop 1 +end