I've committed a slightly rewritten version of the error messages to trunk as rev.269717, see attached.
Thanks for the review and the comments. Harald On 03/12/19 23:19, Thomas Koenig wrote: > Hi Harald, > >> how about the attached version? It is quite verbose and produces >> messages like >> >> Error: Expected list of 'lower-bound-expr:' or list of >> 'lower-bound-expr:upper-bound-expr' at (1) > > I think this way of specifying error messages > > +#define BOUNDS_SPEC_LIST "list of %<lower-bound-expr:upper-bound-expr%>" > > ... > > + gfc_error ("Rank remapping requires a " > + BOUNDS_SPEC_LIST " at %L", > &lvalue->where); > > will cause trouble in translation of the error messages. > > Could you maybe use something like > > + gfc_error ("Rank remapping requires " > + lower and upper bounds at %L", > &lvalue->where); > > and possibly, instead of > > - gfc_error ("Either all or none of the upper bounds" > - " must be specified at %L", &lvalue->where); > + gfc_error ("Rank remapping requires a " > + BOUNDS_SPEC_LIST " at %L", > + &lvalue->where); > return false; > > use > > " Rank remapping requires that all lower and upper bounds be specified" > > ? > > (And I am fairly certain that my versions are not the best possible > ones...) > > So, either something like what you propsed (but without the #defines) > or something like what I wrote above would be OK. > > Regards > > Thomas
Index: gcc/fortran/expr.c =================================================================== --- gcc/fortran/expr.c (revision 269715) +++ gcc/fortran/expr.c (working copy) @@ -3703,6 +3703,7 @@ gfc_ref *ref; bool is_pure, is_implicit_pure, rank_remap; int proc_pointer; + bool same_rank; lhs_attr = gfc_expr_attr (lvalue); if (lvalue->ts.type == BT_UNKNOWN && !lhs_attr.proc_pointer) @@ -3724,6 +3725,7 @@ proc_pointer = lvalue->symtree->n.sym->attr.proc_pointer; rank_remap = false; + same_rank = lvalue->rank == rvalue->rank; for (ref = lvalue->ref; ref; ref = ref->next) { if (ref->type == REF_COMPONENT) @@ -3748,36 +3750,68 @@ lvalue->symtree->n.sym->name, &lvalue->where)) return false; - /* When bounds are given, all lbounds are necessary and either all - or none of the upper bounds; no strides are allowed. If the - upper bounds are present, we may do rank remapping. */ + /* Fortran standard (e.g. F2018, 10.2.2 Pointer assignment): + * + * (C1017) If bounds-spec-list is specified, the number of + * bounds-specs shall equal the rank of data-pointer-object. + * + * If bounds-spec-list appears, it specifies the lower bounds. + * + * (C1018) If bounds-remapping-list is specified, the number of + * bounds-remappings shall equal the rank of data-pointer-object. + * + * If bounds-remapping-list appears, it specifies the upper and + * lower bounds of each dimension of the pointer; the pointer target + * shall be simply contiguous or of rank one. + * + * (C1019) If bounds-remapping-list is not specified, the ranks of + * data-pointer-object and data-target shall be the same. + * + * Thus when bounds are given, all lbounds are necessary and either + * all or none of the upper bounds; no strides are allowed. If the + * upper bounds are present, we may do rank remapping. */ for (dim = 0; dim < ref->u.ar.dimen; ++dim) { - if (!ref->u.ar.start[dim] - || ref->u.ar.dimen_type[dim] != DIMEN_RANGE) + if (ref->u.ar.stride[dim]) { - gfc_error ("Lower bound has to be present at %L", + gfc_error ("Stride must not be present at %L", &lvalue->where); return false; } - if (ref->u.ar.stride[dim]) + if (!same_rank && (!ref->u.ar.start[dim] ||!ref->u.ar.end[dim])) { - gfc_error ("Stride must not be present at %L", - &lvalue->where); + gfc_error ("Rank remapping requires a " + "list of %<lower-bound : upper-bound%> " + "specifications at %L", &lvalue->where); return false; } + if (!ref->u.ar.start[dim] + || ref->u.ar.dimen_type[dim] != DIMEN_RANGE) + { + gfc_error ("Expected list of %<lower-bound :%> or " + "list of %<lower-bound : upper-bound%> " + "specifications at %L", &lvalue->where); + return false; + } if (dim == 0) rank_remap = (ref->u.ar.end[dim] != NULL); else { - if ((rank_remap && !ref->u.ar.end[dim]) - || (!rank_remap && ref->u.ar.end[dim])) + if ((rank_remap && !ref->u.ar.end[dim])) { - gfc_error ("Either all or none of the upper bounds" - " must be specified at %L", &lvalue->where); + gfc_error ("Rank remapping requires a " + "list of %<lower-bound : upper-bound%> " + "specifications at %L", &lvalue->where); return false; } + if (!rank_remap && ref->u.ar.end[dim]) + { + gfc_error ("Expected list of %<lower-bound :%> or " + "list of %<lower-bound : upper-bound%> " + "specifications at %L", &lvalue->where); + return false; + } } } }
Index: gcc/testsuite/gfortran.dg/pointer_remapping_3.f08 =================================================================== --- gcc/testsuite/gfortran.dg/pointer_remapping_3.f08 (revision 269715) +++ gcc/testsuite/gfortran.dg/pointer_remapping_3.f08 (working copy) @@ -3,6 +3,7 @@ ! PR fortran/29785 ! PR fortran/45016 +! PR fortran/60091 ! Check for pointer remapping compile-time errors. ! Contributed by Daniel Kraft, d...@domob.eu. @@ -13,13 +14,13 @@ INTEGER, POINTER :: vec(:), mat(:, :) ! Existence of reference elements. - vec(:) => arr ! { dg-error "Lower bound has to be present" } - vec(5:7:1) => arr ! { dg-error "Stride must not be present" } - mat(1:, 2:5) => arr ! { dg-error "Either all or none of the upper bounds" } - mat(2, 6) => arr ! { dg-error "Expected bounds specification" } + vec(:) => arr ! { dg-error "or list of 'lower-bound : upper-bound'" } + vec(5:7:1) => arr ! { dg-error "Stride must not be present" } + mat(1:,2:5) => arr ! { dg-error "Rank remapping requires a list of " } + mat(1:3,4:) => arr ! { dg-error "Rank remapping requires a list of " } + mat(2, 6) => arr ! { dg-error "Expected bounds specification" } - ! This is bound remapping not rank remapping! - mat(1:, 3:) => arr ! { dg-error "Different ranks" } + mat(1:,3:) => arr ! { dg-error "Rank remapping requires a list of " } ! Invalid remapping target; for non-rank one we already check the F2008 ! error elsewhere. Here, test that not-contiguous target is disallowed Index: gcc/testsuite/gfortran.dg/pointer_remapping_7.f90 =================================================================== --- gcc/testsuite/gfortran.dg/pointer_remapping_7.f90 (revision 269715) +++ gcc/testsuite/gfortran.dg/pointer_remapping_7.f90 (working copy) @@ -4,5 +4,5 @@ ! integer, target :: A(100) integer,pointer :: P(:,:) - p(10,1:) => A ! { dg-error "Lower bound has to be present" } + p(10,1:) => A ! { dg-error "or list of 'lower-bound : upper-bound'" } end