Hi Dominique,
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 did check other compilers. E.g. Intel and Oracle do print messages
using the 'legalese'. But user-friendliness does count, too.)
OK for trunk? Further comments?
Thanks,
Harald
On 03/11/19 10:22, Dominique d'Humières wrote:
> Hi Harald,
>
> The patch looks good to me (although I did not test it), however I don’t like
> the standard legalese in the error messages.
>
> IMO
>
> R1035 bounds-spec is lower-bound-expr :
> R1036 bounds-remapping is lower-bound-expr : upper-bound-exp
>
> should be rephrased in plain English.
>
> Thanks for the work.
>
> Dominique
Index: gcc/fortran/expr.c
===================================================================
--- gcc/fortran/expr.c (revision 269593)
+++ 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,72 @@
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. */
+
+#define BOUNDS_SPEC_LIST "list of %<lower-bound-expr:upper-bound-expr%>"
+#define BOUNDS_REMAPPING_LIST "list of %<lower-bound-expr:%>"
+
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",
+ gfc_error ("Rank remapping requires a "
+ BOUNDS_SPEC_LIST " at %L",
&lvalue->where);
return false;
}
+ if (!ref->u.ar.start[dim]
+ || ref->u.ar.dimen_type[dim] != DIMEN_RANGE)
+ {
+ gfc_error ("Expected " BOUNDS_REMAPPING_LIST " or "
+ BOUNDS_SPEC_LIST " 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 "
+ BOUNDS_SPEC_LIST " at %L",
+ &lvalue->where);
return false;
}
+ if (!rank_remap && ref->u.ar.end[dim])
+ {
+ gfc_error ("Expected " BOUNDS_REMAPPING_LIST " or "
+ BOUNDS_SPEC_LIST " at %L",
+ &lvalue->where);
+ return false;
+ }
}
}
}
Index: gcc/testsuite/gfortran.dg/pointer_remapping_3.f08
===================================================================
--- gcc/testsuite/gfortran.dg/pointer_remapping_3.f08 (revision 269593)
+++ 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, [email protected].
@@ -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-expr:upper-bound-expr'" }
+ 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 269593)
+++ 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-expr:upper-bound-expr'"
}
end