On 12/18/19 7:04 AM, Julian Brown wrote:

This part contains the Fortran front-end support for parsing the new
attach and detach clauses, as well as derived-type members on other
data-movement clauses (copyin, copyout, etc.).
I browsed the patch and it looks mostly fine to me. However, I do have comments related to the array refs.
@@ -3890,9 +3922,6 @@ check_array_not_assumed (gfc_symbol *sym, locus loc, 
const char *name)
  static void
  resolve_oacc_data_clauses (gfc_symbol *sym, locus loc, const char *name)
  {
+         /* Disallow duplicate bare variable references and multiple
+            subarrays of the same array here, but allow multiple components of
+            the same (e.g. derived-type) variable.  For the latter, duplicate
+            components are detected elsewhere.  */
Do we have a test case for "the latter"?
@@ -4470,23 +4514,43 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses 
*omp_clauses,
+               gfc_ref *array_ref = NULL;
+               bool resolved = false;
                if (n->expr)
                  {
-                   if (!gfc_resolve_expr (n->expr)
+                   array_ref = n->expr->ref;
+                   resolved = gfc_resolve_expr (n->expr);
+
+                   /* Look through component refs to find last array
+                      reference.  */
+                   if (openacc)
+                     while (resolved
I would move the "resolved" into the "if" condition as it doesn't change in the while loop.
+                            && array_ref
+                            && (array_ref->type == REF_COMPONENT
+                                || (array_ref->type == REF_ARRAY
+                                    && array_ref->next
+                                    && (array_ref->next->type
+                                        == REF_COMPONENT))))
+                       array_ref = array_ref->next;
+                 }
+               if (array_ref
+                   || (n->expr
+                       && (!resolved || n->expr->expr_type != EXPR_VARIABLE)))
+                 {
+                   if (!resolved
                        || n->expr->expr_type != EXPR_VARIABLE
-                       || n->expr->ref == NULL
-                       || n->expr->ref->next
-                       || n->expr->ref->type != REF_ARRAY)
+                       || array_ref->next
+                       || array_ref->type != REF_ARRAY)
                      gfc_error ("%qs in %s clause at %L is not a proper "
                                 "array section", n->sym->name, name,
                                 &n->where);
-                   else if (n->expr->ref->u.ar.codimen)
+                   else if (array_ref->u.ar.codimen)
                      gfc_error ("Coarrays not supported in %s clause at %L",
                                 name, &n->where);

First, I believe the error message is wrong – coarrays are permitted but only if their local data is accessed; this check checks whether a coindex is present, i.e. whether the variable is accessed on a remote process ("image"). Hence, the error should use something like "Entry shall not be coindexed in %s clause at %L" or something like that.

Secondly, a coarray can exist at different places, e.g.

type t
  integer :: i
end type t
type t2
  integer, allocatable :: i[:]
  type(t), allocatable :: x[:]
end type t2
type(t), allocatable :: A[:], B[:]
type(t) :: D[*]
type(t2) :: C
!$acc data copy(D[2]%i, A[4], B[4]%i, C%i[2], C%x[4]%i)

Here, C is not a coarray. But all those list items in the clause are
coindexed – but your new check will only detect those where the ultimate
component is coindexed. The quickest check for this is "gfc_is_coindexed 
(expr)".

Thirdly, I am not sure whether the following will work with your code:
type t
  integer :: i(5), j(17), k
end type t
type(t) :: x(10)
!$acc data copy (x(:)%k, x(:)%j(3))

This data is strided; I don't quickly see whether that's rejected. (I also
didn't check whether it is valid, but I think it is not.)

+/* Transparently dereference VAR if it is a pointer, reference, etc.
+   according to Fortran semantics.  */
+
+tree
+gfc_auto_dereference_var (gfc_symbol *sym, tree var, bool descriptor_only_p,
+                         bool is_classarray)

I have to admit that 'transparently deference' and 'auto' puzzles me, naming/description wise, but I don't have a good solution; but I like the 'Dereference the expression, where needed' more

+      /* Dereference the expression, where needed.  */
+      se->expr = gfc_auto_dereference_var (sym, se->expr, se->descriptor_only,
+                                          is_classarray);

+++ b/gcc/fortran/trans-openmp.c
+  if (element)
+    {
+      gfc_conv_expr_reference (&se, n->expr);
+      gfc_add_block_to_block (block, &se.pre);
+      ptr = se.expr;
+      OMP_CLAUSE_SIZE (node)
+       = TYPE_SIZE_UNIT (TREE_TYPE (ptr));

This fits nicely on a single line; I think the ';' is in column 64!

Cheers,

Tobias

Reply via email to